CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
feature_extraction_utils.py698 linesDownload Raw Back to transformers
1# Copyright 2021 The HuggingFace Inc. team.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7#     http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14"""15Feature extraction saving/loading class for common feature extractors.16"""17 18import copy19import json20import os21import warnings22from collections import UserDict23from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union24 25import numpy as np26 27from .dynamic_module_utils import custom_object_save28from .utils import (29    FEATURE_EXTRACTOR_NAME,30    PROCESSOR_NAME,31    PushToHubMixin,32    TensorType,33    copy_func,34    download_url,35    is_flax_available,36    is_jax_tensor,37    is_numpy_array,38    is_offline_mode,39    is_remote_url,40    is_tf_available,41    is_torch_available,42    is_torch_device,43    is_torch_dtype,44    logging,45    requires_backends,46)47from .utils.hub import cached_file48 49 50if TYPE_CHECKING:51    from .feature_extraction_sequence_utils import SequenceFeatureExtractor52 53 54logger = logging.get_logger(__name__)55 56PreTrainedFeatureExtractor = Union["SequenceFeatureExtractor"]57 58# type hinting: specifying the type of feature extractor class that inherits from FeatureExtractionMixin59SpecificFeatureExtractorType = TypeVar("SpecificFeatureExtractorType", bound="FeatureExtractionMixin")60 61 62class BatchFeature(UserDict):63    r"""64    Holds the output of the [`~SequenceFeatureExtractor.pad`] and feature extractor specific `__call__` methods.65 66    This class is derived from a python dictionary and can be used as a dictionary.67 68    Args:69        data (`dict`, *optional*):70            Dictionary of lists/arrays/tensors returned by the __call__/pad methods ('input_values', 'attention_mask',71            etc.).72        tensor_type (`Union[None, str, TensorType]`, *optional*):73            You can give a tensor_type here to convert the lists of integers in PyTorch/TensorFlow/Numpy Tensors at74            initialization.75    """76 77    def __init__(self, data: Optional[dict[str, Any]] = None, tensor_type: Union[None, str, TensorType] = None):78        super().__init__(data)79        self.convert_to_tensors(tensor_type=tensor_type)80 81    def __getitem__(self, item: str) -> Any:82        """83        If the key is a string, returns the value of the dict associated to `key` ('input_values', 'attention_mask',84        etc.).85        """86        if isinstance(item, str):87            return self.data[item]88        else:89            raise KeyError("Indexing with integers is not available when using Python based feature extractors")90 91    def __getattr__(self, item: str):92        try:93            return self.data[item]94        except KeyError:95            raise AttributeError96 97    def __getstate__(self):98        return {"data": self.data}99 100    def __setstate__(self, state):101        if "data" in state:102            self.data = state["data"]103 104    def _get_is_as_tensor_fns(self, tensor_type: Optional[Union[str, TensorType]] = None):105        if tensor_type is None:106            return None, None107 108        # Convert to TensorType109        if not isinstance(tensor_type, TensorType):110            tensor_type = TensorType(tensor_type)111 112        # Get a function reference for the correct framework113        if tensor_type == TensorType.TENSORFLOW:114            logger.warning_once(115                "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We "116                "recommend migrating to PyTorch classes or pinning your version of Transformers."117            )118            if not is_tf_available():119                raise ImportError(120                    "Unable to convert output to TensorFlow tensors format, TensorFlow is not installed."121                )122            import tensorflow as tf123 124            as_tensor = tf.constant125            is_tensor = tf.is_tensor126        elif tensor_type == TensorType.PYTORCH:127            if not is_torch_available():128                raise ImportError("Unable to convert output to PyTorch tensors format, PyTorch is not installed.")129            import torch130 131            def as_tensor(value):132                if isinstance(value, (list, tuple)) and len(value) > 0:133                    if isinstance(value[0], np.ndarray):134                        value = np.array(value)135                    elif (136                        isinstance(value[0], (list, tuple))137                        and len(value[0]) > 0138                        and isinstance(value[0][0], np.ndarray)139                    ):140                        value = np.array(value)141                if isinstance(value, np.ndarray):142                    return torch.from_numpy(value)143                else:144                    return torch.tensor(value)145 146            is_tensor = torch.is_tensor147        elif tensor_type == TensorType.JAX:148            logger.warning_once(149                "TensorFlow and JAX classes are deprecated and will be removed in Transformers v5. We "150                "recommend migrating to PyTorch classes or pinning your version of Transformers."151            )152            if not is_flax_available():153                raise ImportError("Unable to convert output to JAX tensors format, JAX is not installed.")154            import jax.numpy as jnp  # noqa: F811155 156            as_tensor = jnp.array157            is_tensor = is_jax_tensor158        else:159 160            def as_tensor(value, dtype=None):161                if isinstance(value, (list, tuple)) and isinstance(value[0], (list, tuple, np.ndarray)):162                    value_lens = [len(val) for val in value]163                    if len(set(value_lens)) > 1 and dtype is None:164                        # we have a ragged list so handle explicitly165                        value = as_tensor([np.asarray(val) for val in value], dtype=object)166                return np.asarray(value, dtype=dtype)167 168            is_tensor = is_numpy_array169        return is_tensor, as_tensor170 171    def convert_to_tensors(self, tensor_type: Optional[Union[str, TensorType]] = None):172        """173        Convert the inner content to tensors.174 175        Args:176            tensor_type (`str` or [`~utils.TensorType`], *optional*):177                The type of tensors to use. If `str`, should be one of the values of the enum [`~utils.TensorType`]. If178                `None`, no modification is done.179        """180        if tensor_type is None:181            return self182 183        is_tensor, as_tensor = self._get_is_as_tensor_fns(tensor_type)184 185        # Do the tensor conversion in batch186        for key, value in self.items():187            try:188                if not is_tensor(value):189                    tensor = as_tensor(value)190 191                    self[key] = tensor192            except:  # noqa E722193                if key == "overflowing_values":194                    raise ValueError("Unable to create tensor returning overflowing values of different lengths. ")195                raise ValueError(196                    "Unable to create tensor, you should probably activate padding "197                    "with 'padding=True' to have batched tensors with the same length."198                )199 200        return self201 202    def to(self, *args, **kwargs) -> "BatchFeature":203        """204        Send all values to device by calling `v.to(*args, **kwargs)` (PyTorch only). This should support casting in205        different `dtypes` and sending the `BatchFeature` to a different `device`.206 207        Args:208            args (`Tuple`):209                Will be passed to the `to(...)` function of the tensors.210            kwargs (`Dict`, *optional*):211                Will be passed to the `to(...)` function of the tensors.212                To enable asynchronous data transfer, set the `non_blocking` flag in `kwargs` (defaults to `False`).213 214        Returns:215            [`BatchFeature`]: The same instance after modification.216        """217        requires_backends(self, ["torch"])218        import torch219 220        device = kwargs.get("device")221        non_blocking = kwargs.get("non_blocking", False)222        # Check if the args are a device or a dtype223        if device is None and len(args) > 0:224            # device should be always the first argument225            arg = args[0]226            if is_torch_dtype(arg):227                # The first argument is a dtype228                pass229            elif isinstance(arg, str) or is_torch_device(arg) or isinstance(arg, int):230                device = arg231            else:232                # it's something else233                raise ValueError(f"Attempting to cast a BatchFeature to type {str(arg)}. This is not supported.")234 235        # We cast only floating point tensors to avoid issues with tokenizers casting `LongTensor` to `FloatTensor`236        def maybe_to(v):237            # check if v is a floating point238            if isinstance(v, torch.Tensor) and torch.is_floating_point(v):239                # cast and send to device240                return v.to(*args, **kwargs)241            elif isinstance(v, torch.Tensor) and device is not None:242                return v.to(device=device, non_blocking=non_blocking)243            else:244                return v245 246        self.data = {k: maybe_to(v) for k, v in self.items()}247        return self248 249 250class FeatureExtractionMixin(PushToHubMixin):251    """252    This is a feature extraction mixin used to provide saving/loading functionality for sequential and image feature253    extractors.254    """255 256    _auto_class = None257 258    def __init__(self, **kwargs):259        """Set elements of `kwargs` as attributes."""260        # Pop "processor_class" as it should be saved as private attribute261        self._processor_class = kwargs.pop("processor_class", None)262        # Additional attributes without default values263        for key, value in kwargs.items():264            try:265                setattr(self, key, value)266            except AttributeError as err:267                logger.error(f"Can't set {key} with value {value} for {self}")268                raise err269 270    def _set_processor_class(self, processor_class: str):271        """Sets processor class as an attribute."""272        self._processor_class = processor_class273 274    @classmethod275    def from_pretrained(276        cls: type[SpecificFeatureExtractorType],277        pretrained_model_name_or_path: Union[str, os.PathLike],278        cache_dir: Optional[Union[str, os.PathLike]] = None,279        force_download: bool = False,280        local_files_only: bool = False,281        token: Optional[Union[str, bool]] = None,282        revision: str = "main",283        **kwargs,284    ) -> SpecificFeatureExtractorType:285        r"""286        Instantiate a type of [`~feature_extraction_utils.FeatureExtractionMixin`] from a feature extractor, *e.g.* a287        derived class of [`SequenceFeatureExtractor`].288 289        Args:290            pretrained_model_name_or_path (`str` or `os.PathLike`):291                This can be either:292 293                - a string, the *model id* of a pretrained feature_extractor hosted inside a model repo on294                  huggingface.co.295                - a path to a *directory* containing a feature extractor file saved using the296                  [`~feature_extraction_utils.FeatureExtractionMixin.save_pretrained`] method, e.g.,297                  `./my_model_directory/`.298                - a path or url to a saved feature extractor JSON *file*, e.g.,299                  `./my_model_directory/preprocessor_config.json`.300            cache_dir (`str` or `os.PathLike`, *optional*):301                Path to a directory in which a downloaded pretrained model feature extractor should be cached if the302                standard cache should not be used.303            force_download (`bool`, *optional*, defaults to `False`):304                Whether or not to force to (re-)download the feature extractor files and override the cached versions305                if they exist.306            resume_download:307                Deprecated and ignored. All downloads are now resumed by default when possible.308                Will be removed in v5 of Transformers.309            proxies (`dict[str, str]`, *optional*):310                A dictionary of proxy servers to use by protocol or endpoint, e.g., `{'http': 'foo.bar:3128',311                'http://hostname': 'foo.bar:4012'}.` The proxies are used on each request.312            token (`str` or `bool`, *optional*):313                The token to use as HTTP bearer authorization for remote files. If `True`, or not specified, will use314                the token generated when running `hf auth login` (stored in `~/.huggingface`).315            revision (`str`, *optional*, defaults to `"main"`):316                The specific model version to use. It can be a branch name, a tag name, or a commit id, since we use a317                git-based system for storing models and other artifacts on huggingface.co, so `revision` can be any318                identifier allowed by git.319 320 321                <Tip>322 323                To test a pull request you made on the Hub, you can pass `revision="refs/pr/<pr_number>"`.324 325                </Tip>326 327            return_unused_kwargs (`bool`, *optional*, defaults to `False`):328                If `False`, then this function returns just the final feature extractor object. If `True`, then this329                functions returns a `Tuple(feature_extractor, unused_kwargs)` where *unused_kwargs* is a dictionary330                consisting of the key/value pairs whose keys are not feature extractor attributes: i.e., the part of331                `kwargs` which has not been used to update `feature_extractor` and is otherwise ignored.332            kwargs (`dict[str, Any]`, *optional*):333                The values in kwargs of any keys which are feature extractor attributes will be used to override the334                loaded values. Behavior concerning key/value pairs whose keys are *not* feature extractor attributes is335                controlled by the `return_unused_kwargs` keyword parameter.336 337        Returns:338            A feature extractor of type [`~feature_extraction_utils.FeatureExtractionMixin`].339 340        Examples:341 342        ```python343        # We can't instantiate directly the base class *FeatureExtractionMixin* nor *SequenceFeatureExtractor* so let's show the examples on a344        # derived class: *Wav2Vec2FeatureExtractor*345        feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(346            "facebook/wav2vec2-base-960h"347        )  # Download feature_extraction_config from huggingface.co and cache.348        feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(349            "./test/saved_model/"350        )  # E.g. feature_extractor (or model) was saved using *save_pretrained('./test/saved_model/')*351        feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained("./test/saved_model/preprocessor_config.json")352        feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(353            "facebook/wav2vec2-base-960h", return_attention_mask=False, foo=False354        )355        assert feature_extractor.return_attention_mask is False356        feature_extractor, unused_kwargs = Wav2Vec2FeatureExtractor.from_pretrained(357            "facebook/wav2vec2-base-960h", return_attention_mask=False, foo=False, return_unused_kwargs=True358        )359        assert feature_extractor.return_attention_mask is False360        assert unused_kwargs == {"foo": False}361        ```"""362        kwargs["cache_dir"] = cache_dir363        kwargs["force_download"] = force_download364        kwargs["local_files_only"] = local_files_only365        kwargs["revision"] = revision366 367        use_auth_token = kwargs.pop("use_auth_token", None)368        if use_auth_token is not None:369            warnings.warn(370                "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.",371                FutureWarning,372            )373            if token is not None:374                raise ValueError(375                    "`token` and `use_auth_token` are both specified. Please set only the argument `token`."376                )377            token = use_auth_token378 379        if token is not None:380            kwargs["token"] = token381 382        feature_extractor_dict, kwargs = cls.get_feature_extractor_dict(pretrained_model_name_or_path, **kwargs)383 384        return cls.from_dict(feature_extractor_dict, **kwargs)385 386    def save_pretrained(self, save_directory: Union[str, os.PathLike], push_to_hub: bool = False, **kwargs):387        """388        Save a feature_extractor object to the directory `save_directory`, so that it can be re-loaded using the389        [`~feature_extraction_utils.FeatureExtractionMixin.from_pretrained`] class method.390 391        Args:392            save_directory (`str` or `os.PathLike`):393                Directory where the feature extractor JSON file will be saved (will be created if it does not exist).394            push_to_hub (`bool`, *optional*, defaults to `False`):395                Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the396                repository you want to push to with `repo_id` (will default to the name of `save_directory` in your397                namespace).398            kwargs (`dict[str, Any]`, *optional*):399                Additional key word arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.400        """401        use_auth_token = kwargs.pop("use_auth_token", None)402 403        if use_auth_token is not None:404            warnings.warn(405                "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.",406                FutureWarning,407            )408            if kwargs.get("token") is not None:409                raise ValueError(410                    "`token` and `use_auth_token` are both specified. Please set only the argument `token`."411                )412            kwargs["token"] = use_auth_token413 414        if os.path.isfile(save_directory):415            raise AssertionError(f"Provided path ({save_directory}) should be a directory, not a file")416 417        os.makedirs(save_directory, exist_ok=True)418 419        if push_to_hub:420            commit_message = kwargs.pop("commit_message", None)421            repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1])422            repo_id = self._create_repo(repo_id, **kwargs)423            files_timestamps = self._get_files_timestamps(save_directory)424 425        # If we have a custom config, we copy the file defining it in the folder and set the attributes so it can be426        # loaded from the Hub.427        if self._auto_class is not None:428            custom_object_save(self, save_directory, config=self)429 430        # If we save using the predefined names, we can load using `from_pretrained`431        output_feature_extractor_file = os.path.join(save_directory, FEATURE_EXTRACTOR_NAME)432 433        self.to_json_file(output_feature_extractor_file)434        logger.info(f"Feature extractor saved in {output_feature_extractor_file}")435 436        if push_to_hub:437            self._upload_modified_files(438                save_directory,439                repo_id,440                files_timestamps,441                commit_message=commit_message,442                token=kwargs.get("token"),443            )444 445        return [output_feature_extractor_file]446 447    @classmethod448    def get_feature_extractor_dict(449        cls, pretrained_model_name_or_path: Union[str, os.PathLike], **kwargs450    ) -> tuple[dict[str, Any], dict[str, Any]]:451        """452        From a `pretrained_model_name_or_path`, resolve to a dictionary of parameters, to be used for instantiating a453        feature extractor of type [`~feature_extraction_utils.FeatureExtractionMixin`] using `from_dict`.454 455        Parameters:456            pretrained_model_name_or_path (`str` or `os.PathLike`):457                The identifier of the pre-trained checkpoint from which we want the dictionary of parameters.458 459        Returns:460            `tuple[Dict, Dict]`: The dictionary(ies) that will be used to instantiate the feature extractor object.461        """462        cache_dir = kwargs.pop("cache_dir", None)463        force_download = kwargs.pop("force_download", False)464        resume_download = kwargs.pop("resume_download", None)465        proxies = kwargs.pop("proxies", None)466        subfolder = kwargs.pop("subfolder", None)467        token = kwargs.pop("token", None)468        use_auth_token = kwargs.pop("use_auth_token", None)469        local_files_only = kwargs.pop("local_files_only", False)470        revision = kwargs.pop("revision", None)471 472        if use_auth_token is not None:473            warnings.warn(474                "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.",475                FutureWarning,476            )477            if token is not None:478                raise ValueError(479                    "`token` and `use_auth_token` are both specified. Please set only the argument `token`."480                )481            token = use_auth_token482 483        from_pipeline = kwargs.pop("_from_pipeline", None)484        from_auto_class = kwargs.pop("_from_auto", False)485 486        user_agent = {"file_type": "feature extractor", "from_auto_class": from_auto_class}487        if from_pipeline is not None:488            user_agent["using_pipeline"] = from_pipeline489 490        if is_offline_mode() and not local_files_only:491            logger.info("Offline mode: forcing local_files_only=True")492            local_files_only = True493 494        pretrained_model_name_or_path = str(pretrained_model_name_or_path)495        is_local = os.path.isdir(pretrained_model_name_or_path)496        if os.path.isdir(pretrained_model_name_or_path):497            feature_extractor_file = os.path.join(pretrained_model_name_or_path, FEATURE_EXTRACTOR_NAME)498        if os.path.isfile(pretrained_model_name_or_path):499            resolved_feature_extractor_file = pretrained_model_name_or_path500            is_local = True501        elif is_remote_url(pretrained_model_name_or_path):502            feature_extractor_file = pretrained_model_name_or_path503            resolved_feature_extractor_file = download_url(pretrained_model_name_or_path)504        else:505            feature_extractor_file = FEATURE_EXTRACTOR_NAME506            try:507                # Load from local folder or from cache or download from model Hub and cache508                resolved_feature_extractor_files = [509                    resolved_file510                    for filename in [feature_extractor_file, PROCESSOR_NAME]511                    if (512                        resolved_file := cached_file(513                            pretrained_model_name_or_path,514                            filename=filename,515                            cache_dir=cache_dir,516                            force_download=force_download,517                            proxies=proxies,518                            resume_download=resume_download,519                            local_files_only=local_files_only,520                            subfolder=subfolder,521                            token=token,522                            user_agent=user_agent,523                            revision=revision,524                            _raise_exceptions_for_missing_entries=False,525                        )526                    )527                    is not None528                ]529                resolved_feature_extractor_file = resolved_feature_extractor_files[0]530            except OSError:531                # Raise any environment error raise by `cached_file`. It will have a helpful error message adapted to532                # the original exception.533                raise534            except Exception:535                # For any other exception, we throw a generic error.536                raise OSError(537                    f"Can't load feature extractor for '{pretrained_model_name_or_path}'. If you were trying to load"538                    " it from 'https://huggingface.co/models', make sure you don't have a local directory with the"539                    f" same name. Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a"540                    f" directory containing a {FEATURE_EXTRACTOR_NAME} file"541                )542 543        try:544            # Load feature_extractor dict545            with open(resolved_feature_extractor_file, encoding="utf-8") as reader:546                text = reader.read()547            feature_extractor_dict = json.loads(text)548            feature_extractor_dict = feature_extractor_dict.get("feature_extractor", feature_extractor_dict)549 550        except json.JSONDecodeError:551            raise OSError(552                f"It looks like the config file at '{resolved_feature_extractor_file}' is not a valid JSON file."553            )554 555        if is_local:556            logger.info(f"loading configuration file {resolved_feature_extractor_file}")557        else:558            logger.info(559                f"loading configuration file {feature_extractor_file} from cache at {resolved_feature_extractor_file}"560            )561 562        return feature_extractor_dict, kwargs563 564    @classmethod565    def from_dict(566        cls, feature_extractor_dict: dict[str, Any], **kwargs567    ) -> Union["FeatureExtractionMixin", tuple["FeatureExtractionMixin", dict[str, Any]]]:568        """569        Instantiates a type of [`~feature_extraction_utils.FeatureExtractionMixin`] from a Python dictionary of570        parameters.571 572        Args:573            feature_extractor_dict (`dict[str, Any]`):574                Dictionary that will be used to instantiate the feature extractor object. Such a dictionary can be575                retrieved from a pretrained checkpoint by leveraging the576                [`~feature_extraction_utils.FeatureExtractionMixin.to_dict`] method.577            kwargs (`dict[str, Any]`):578                Additional parameters from which to initialize the feature extractor object.579 580        Returns:581            [`~feature_extraction_utils.FeatureExtractionMixin`]: The feature extractor object instantiated from those582            parameters.583        """584        return_unused_kwargs = kwargs.pop("return_unused_kwargs", False)585 586        # Update feature_extractor with kwargs if needed587        to_remove = []588        for key, value in kwargs.items():589            if key in feature_extractor_dict:590                feature_extractor_dict[key] = value591                to_remove.append(key)592        for key in to_remove:593            kwargs.pop(key, None)594 595        feature_extractor = cls(**feature_extractor_dict)596 597        logger.info(f"Feature extractor {feature_extractor}")598        if return_unused_kwargs:599            return feature_extractor, kwargs600        else:601            return feature_extractor602 603    def to_dict(self) -> dict[str, Any]:604        """605        Serializes this instance to a Python dictionary. Returns:606            `dict[str, Any]`: Dictionary of all the attributes that make up this configuration instance.607        """608        output = copy.deepcopy(self.__dict__)609        output["feature_extractor_type"] = self.__class__.__name__610        if "mel_filters" in output:611            del output["mel_filters"]612        if "window" in output:613            del output["window"]614        return output615 616    @classmethod617    def from_json_file(cls, json_file: Union[str, os.PathLike]) -> "FeatureExtractionMixin":618        """619        Instantiates a feature extractor of type [`~feature_extraction_utils.FeatureExtractionMixin`] from the path to620        a JSON file of parameters.621 622        Args:623            json_file (`str` or `os.PathLike`):624                Path to the JSON file containing the parameters.625 626        Returns:627            A feature extractor of type [`~feature_extraction_utils.FeatureExtractionMixin`]: The feature_extractor628            object instantiated from that JSON file.629        """630        with open(json_file, encoding="utf-8") as reader:631            text = reader.read()632        feature_extractor_dict = json.loads(text)633        return cls(**feature_extractor_dict)634 635    def to_json_string(self) -> str:636        """637        Serializes this instance to a JSON string.638 639        Returns:640            `str`: String containing all the attributes that make up this feature_extractor instance in JSON format.641        """642        dictionary = self.to_dict()643 644        for key, value in dictionary.items():645            if isinstance(value, np.ndarray):646                dictionary[key] = value.tolist()647 648        # make sure private name "_processor_class" is correctly649        # saved as "processor_class"650        _processor_class = dictionary.pop("_processor_class", None)651        if _processor_class is not None:652            dictionary["processor_class"] = _processor_class653 654        return json.dumps(dictionary, indent=2, sort_keys=True) + "\n"655 656    def to_json_file(self, json_file_path: Union[str, os.PathLike]):657        """658        Save this instance to a JSON file.659 660        Args:661            json_file_path (`str` or `os.PathLike`):662                Path to the JSON file in which this feature_extractor instance's parameters will be saved.663        """664        with open(json_file_path, "w", encoding="utf-8") as writer:665            writer.write(self.to_json_string())666 667    def __repr__(self):668        return f"{self.__class__.__name__} {self.to_json_string()}"669 670    @classmethod671    def register_for_auto_class(cls, auto_class="AutoFeatureExtractor"):672        """673        Register this class with a given auto class. This should only be used for custom feature extractors as the ones674        in the library are already mapped with `AutoFeatureExtractor`.675 676 677 678        Args:679            auto_class (`str` or `type`, *optional*, defaults to `"AutoFeatureExtractor"`):680                The auto class to register this new feature extractor with.681        """682        if not isinstance(auto_class, str):683            auto_class = auto_class.__name__684 685        import transformers.models.auto as auto_module686 687        if not hasattr(auto_module, auto_class):688            raise ValueError(f"{auto_class} is not a valid auto class.")689 690        cls._auto_class = auto_class691 692 693FeatureExtractionMixin.push_to_hub = copy_func(FeatureExtractionMixin.push_to_hub)694if FeatureExtractionMixin.push_to_hub.__doc__ is not None:695    FeatureExtractionMixin.push_to_hub.__doc__ = FeatureExtractionMixin.push_to_hub.__doc__.format(696        object="feature extractor", object_class="AutoFeatureExtractor", object_files="feature extractor file"697    )698 
Aluode/PerceptionLabPortable · CoolFace