File size: 4,105 Bytes
9e3b8ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import inspect
import warnings
from typing import Any

from packaging import version

from ..utils import logging


logger = logging.get_logger(__name__)

_TORCH_DTYPE_DEPRECATION_MESSAGE = "Please use `dtype` instead."


def _resolve_dtype(dtype, torch_dtype):
    """Resolve the deprecated `torch_dtype` argument into `dtype`."""
    if torch_dtype is None:
        return dtype
    if dtype is not None:
        raise ValueError(
            "You have passed both `dtype` and `torch_dtype`. Please only pass `dtype`, `torch_dtype` is deprecated."
        )
    deprecate("torch_dtype", "1.0.0", _TORCH_DTYPE_DEPRECATION_MESSAGE)
    return torch_dtype


# Mapping for deprecated Transformers classes to their replacements
# This is used to handle models that reference deprecated class names in their configs
# Reference: https://github.com/huggingface/transformers/issues/40822
# Format: {
#     "DeprecatedClassName": {
#         "new_class": "NewClassName",
#         "transformers_version": (">=", "5.0.0"),  # (operation, version) tuple
#     }
# }
_TRANSFORMERS_CLASS_REMAPPING = {
    "CLIPFeatureExtractor": {
        "new_class": "CLIPImageProcessor",
        "transformers_version": (">", "4.57.0"),
    },
}


def _maybe_remap_transformers_class(class_name: str) -> str | None:
    """
    Check if a Transformers class should be remapped to a newer version.

    Args:
        class_name: The name of the class to check

    Returns:
        The new class name if remapping should occur, None otherwise
    """
    if class_name not in _TRANSFORMERS_CLASS_REMAPPING:
        return None

    from .import_utils import is_transformers_version

    mapping = _TRANSFORMERS_CLASS_REMAPPING[class_name]
    operation, required_version = mapping["transformers_version"]

    # Only remap if the transformers version meets the requirement
    if is_transformers_version(operation, required_version):
        new_class = mapping["new_class"]
        logger.warning(f"{class_name} appears to have been deprecated in transformers. Using {new_class} instead.")
        return mapping["new_class"]

    return None


def deprecate(*args, take_from: dict | Any | None = None, standard_warn=True, stacklevel=2):
    from .. import __version__

    deprecated_kwargs = take_from
    values = ()
    if not isinstance(args[0], tuple):
        args = (args,)

    for attribute, version_name, message in args:
        if version.parse(version.parse(__version__).base_version) >= version.parse(version_name):
            raise ValueError(
                f"The deprecation tuple {(attribute, version_name, message)} should be removed since diffusers'"
                f" version {__version__} is >= {version_name}"
            )

        warning = None
        if isinstance(deprecated_kwargs, dict) and attribute in deprecated_kwargs:
            values += (deprecated_kwargs.pop(attribute),)
            warning = f"The `{attribute}` argument is deprecated and will be removed in version {version_name}."
        elif hasattr(deprecated_kwargs, attribute):
            values += (getattr(deprecated_kwargs, attribute),)
            warning = f"The `{attribute}` attribute is deprecated and will be removed in version {version_name}."
        elif deprecated_kwargs is None:
            warning = f"`{attribute}` is deprecated and will be removed in version {version_name}."

        if warning is not None:
            warning = warning + " " if standard_warn else ""
            warnings.warn(warning + message, FutureWarning, stacklevel=stacklevel)

    if isinstance(deprecated_kwargs, dict) and len(deprecated_kwargs) > 0:
        call_frame = inspect.getouterframes(inspect.currentframe())[1]
        filename = call_frame.filename
        line_number = call_frame.lineno
        function = call_frame.function
        key, value = next(iter(deprecated_kwargs.items()))
        raise TypeError(f"{function} in {filename} line {line_number - 1} got an unexpected keyword argument `{key}`")

    if len(values) == 0:
        return
    elif len(values) == 1:
        return values[0]
    return values