Aluode/PerceptionLabPortable
0
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 