Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +2 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/AUTHORS.rst +7 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/INSTALLER +1 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/LICENSE +21 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/METADATA +106 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/RECORD +32 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/WHEEL +5 -0
- venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/top_level.txt +1 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/INSTALLER +1 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/LICENSE +201 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/METADATA +372 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/RECORD +0 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/REQUESTED +0 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/WHEEL +5 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/entry_points.txt +2 -0
- venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/top_level.txt +1 -0
- venv/lib/python3.10/site-packages/diffusers/__init__.py +1244 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/callbacks.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/configuration_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/dependency_versions_check.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/dependency_versions_table.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/image_processor.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/optimization.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/training_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/__pycache__/video_processor.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/callbacks.py +209 -0
- venv/lib/python3.10/site-packages/diffusers/configuration_utils.py +760 -0
- venv/lib/python3.10/site-packages/diffusers/dependency_versions_check.py +34 -0
- venv/lib/python3.10/site-packages/diffusers/dependency_versions_table.py +53 -0
- venv/lib/python3.10/site-packages/diffusers/image_processor.py +1319 -0
- venv/lib/python3.10/site-packages/diffusers/optimization.py +361 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__init__.py +860 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/auto_pipeline.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/free_init_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/free_noise_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/onnx_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_flax_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_loading_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/transformers_loading_utils.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/auto_pipeline.py +1175 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/free_init_utils.py +187 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/free_noise_utils.py +596 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/onnx_utils.py +230 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_flax_utils.py +610 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_loading_utils.py +1156 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_utils.py +0 -0
- venv/lib/python3.10/site-packages/diffusers/pipelines/stable_diffusion/__init__.py +195 -0
.gitattributes
CHANGED
|
@@ -67,3 +67,5 @@ venv/bin/python3.10 filter=lfs diff=lfs merge=lfs -text
|
|
| 67 |
venv/bin/uv filter=lfs diff=lfs merge=lfs -text
|
| 68 |
venv/lib/python3.10/site-packages/chardet/__pycache__/johabfreq.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
|
| 69 |
venv/lib/python3.10/site-packages/nacl/_sodium.abi3.so filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 67 |
venv/bin/uv filter=lfs diff=lfs merge=lfs -text
|
| 68 |
venv/lib/python3.10/site-packages/chardet/__pycache__/johabfreq.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
|
| 69 |
venv/lib/python3.10/site-packages/nacl/_sodium.abi3.so filter=lfs diff=lfs merge=lfs -text
|
| 70 |
+
venv/lib/python3.10/site-packages/pygments/lexers/__pycache__/lisp.cpython-310.pyc filter=lfs diff=lfs merge=lfs -text
|
| 71 |
+
venv/lib/python3.10/site-packages/wrapt/_wrappers.cpython-310-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/AUTHORS.rst
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Authors
|
| 2 |
+
=======
|
| 3 |
+
|
| 4 |
+
``pyjwt`` is currently written and maintained by `Jose Padilla <https://github.com/jpadilla>`_.
|
| 5 |
+
Originally written and maintained by `Jeff Lindsay <https://github.com/progrium>`_.
|
| 6 |
+
|
| 7 |
+
A full list of contributors can be found on GitHub’s `overview <https://github.com/jpadilla/pyjwt/graphs/contributors>`_.
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
The MIT License (MIT)
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2015-2022 José Padilla
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: PyJWT
|
| 3 |
+
Version: 2.10.1
|
| 4 |
+
Summary: JSON Web Token implementation in Python
|
| 5 |
+
Author-email: Jose Padilla <hello@jpadilla.com>
|
| 6 |
+
License: MIT
|
| 7 |
+
Project-URL: Homepage, https://github.com/jpadilla/pyjwt
|
| 8 |
+
Keywords: json,jwt,security,signing,token,web
|
| 9 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 10 |
+
Classifier: Intended Audience :: Developers
|
| 11 |
+
Classifier: License :: OSI Approved :: MIT License
|
| 12 |
+
Classifier: Natural Language :: English
|
| 13 |
+
Classifier: Programming Language :: Python
|
| 14 |
+
Classifier: Programming Language :: Python :: 3
|
| 15 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 16 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 21 |
+
Classifier: Topic :: Utilities
|
| 22 |
+
Requires-Python: >=3.9
|
| 23 |
+
Description-Content-Type: text/x-rst
|
| 24 |
+
License-File: LICENSE
|
| 25 |
+
License-File: AUTHORS.rst
|
| 26 |
+
Provides-Extra: crypto
|
| 27 |
+
Requires-Dist: cryptography>=3.4.0; extra == "crypto"
|
| 28 |
+
Provides-Extra: dev
|
| 29 |
+
Requires-Dist: coverage[toml]==5.0.4; extra == "dev"
|
| 30 |
+
Requires-Dist: cryptography>=3.4.0; extra == "dev"
|
| 31 |
+
Requires-Dist: pre-commit; extra == "dev"
|
| 32 |
+
Requires-Dist: pytest<7.0.0,>=6.0.0; extra == "dev"
|
| 33 |
+
Requires-Dist: sphinx; extra == "dev"
|
| 34 |
+
Requires-Dist: sphinx-rtd-theme; extra == "dev"
|
| 35 |
+
Requires-Dist: zope.interface; extra == "dev"
|
| 36 |
+
Provides-Extra: docs
|
| 37 |
+
Requires-Dist: sphinx; extra == "docs"
|
| 38 |
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
| 39 |
+
Requires-Dist: zope.interface; extra == "docs"
|
| 40 |
+
Provides-Extra: tests
|
| 41 |
+
Requires-Dist: coverage[toml]==5.0.4; extra == "tests"
|
| 42 |
+
Requires-Dist: pytest<7.0.0,>=6.0.0; extra == "tests"
|
| 43 |
+
|
| 44 |
+
PyJWT
|
| 45 |
+
=====
|
| 46 |
+
|
| 47 |
+
.. image:: https://github.com/jpadilla/pyjwt/workflows/CI/badge.svg
|
| 48 |
+
:target: https://github.com/jpadilla/pyjwt/actions?query=workflow%3ACI
|
| 49 |
+
|
| 50 |
+
.. image:: https://img.shields.io/pypi/v/pyjwt.svg
|
| 51 |
+
:target: https://pypi.python.org/pypi/pyjwt
|
| 52 |
+
|
| 53 |
+
.. image:: https://codecov.io/gh/jpadilla/pyjwt/branch/master/graph/badge.svg
|
| 54 |
+
:target: https://codecov.io/gh/jpadilla/pyjwt
|
| 55 |
+
|
| 56 |
+
.. image:: https://readthedocs.org/projects/pyjwt/badge/?version=stable
|
| 57 |
+
:target: https://pyjwt.readthedocs.io/en/stable/
|
| 58 |
+
|
| 59 |
+
A Python implementation of `RFC 7519 <https://tools.ietf.org/html/rfc7519>`_. Original implementation was written by `@progrium <https://github.com/progrium>`_.
|
| 60 |
+
|
| 61 |
+
Sponsor
|
| 62 |
+
-------
|
| 63 |
+
|
| 64 |
+
.. |auth0-logo| image:: https://github.com/user-attachments/assets/ee98379e-ee76-4bcb-943a-e25c4ea6d174
|
| 65 |
+
:width: 160px
|
| 66 |
+
|
| 67 |
+
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
| 68 |
+
| |auth0-logo| | If you want to quickly add secure token-based authentication to Python projects, feel free to check Auth0's Python SDK and free plan at `auth0.com/signup <https://auth0.com/signup?utm_source=external_sites&utm_medium=pyjwt&utm_campaign=devn_signup>`_. |
|
| 69 |
+
+--------------+-----------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
| 70 |
+
|
| 71 |
+
Installing
|
| 72 |
+
----------
|
| 73 |
+
|
| 74 |
+
Install with **pip**:
|
| 75 |
+
|
| 76 |
+
.. code-block:: console
|
| 77 |
+
|
| 78 |
+
$ pip install PyJWT
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
Usage
|
| 82 |
+
-----
|
| 83 |
+
|
| 84 |
+
.. code-block:: pycon
|
| 85 |
+
|
| 86 |
+
>>> import jwt
|
| 87 |
+
>>> encoded = jwt.encode({"some": "payload"}, "secret", algorithm="HS256")
|
| 88 |
+
>>> print(encoded)
|
| 89 |
+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg
|
| 90 |
+
>>> jwt.decode(encoded, "secret", algorithms=["HS256"])
|
| 91 |
+
{'some': 'payload'}
|
| 92 |
+
|
| 93 |
+
Documentation
|
| 94 |
+
-------------
|
| 95 |
+
|
| 96 |
+
View the full docs online at https://pyjwt.readthedocs.io/en/stable/
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
Tests
|
| 100 |
+
-----
|
| 101 |
+
|
| 102 |
+
You can run tests from the project root after cloning with:
|
| 103 |
+
|
| 104 |
+
.. code-block:: console
|
| 105 |
+
|
| 106 |
+
$ tox
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
PyJWT-2.10.1.dist-info/AUTHORS.rst,sha256=klzkNGECnu2_VY7At89_xLBF3vUSDruXk3xwgUBxzwc,322
|
| 2 |
+
PyJWT-2.10.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 3 |
+
PyJWT-2.10.1.dist-info/LICENSE,sha256=eXp6ICMdTEM-nxkR2xcx0GtYKLmPSZgZoDT3wPVvXOU,1085
|
| 4 |
+
PyJWT-2.10.1.dist-info/METADATA,sha256=EkewF6D6KU8SGaaQzVYfxUUU1P_gs_dp1pYTkoYvAx8,3990
|
| 5 |
+
PyJWT-2.10.1.dist-info/RECORD,,
|
| 6 |
+
PyJWT-2.10.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
| 7 |
+
PyJWT-2.10.1.dist-info/top_level.txt,sha256=RP5DHNyJbMq2ka0FmfTgoSaQzh7e3r5XuCWCO8a00k8,4
|
| 8 |
+
jwt/__init__.py,sha256=VB2vFKuboTjcDGeZ8r-UqK_dz3NsQSQEqySSICby8Xg,1711
|
| 9 |
+
jwt/__pycache__/__init__.cpython-310.pyc,,
|
| 10 |
+
jwt/__pycache__/algorithms.cpython-310.pyc,,
|
| 11 |
+
jwt/__pycache__/api_jwk.cpython-310.pyc,,
|
| 12 |
+
jwt/__pycache__/api_jws.cpython-310.pyc,,
|
| 13 |
+
jwt/__pycache__/api_jwt.cpython-310.pyc,,
|
| 14 |
+
jwt/__pycache__/exceptions.cpython-310.pyc,,
|
| 15 |
+
jwt/__pycache__/help.cpython-310.pyc,,
|
| 16 |
+
jwt/__pycache__/jwk_set_cache.cpython-310.pyc,,
|
| 17 |
+
jwt/__pycache__/jwks_client.cpython-310.pyc,,
|
| 18 |
+
jwt/__pycache__/types.cpython-310.pyc,,
|
| 19 |
+
jwt/__pycache__/utils.cpython-310.pyc,,
|
| 20 |
+
jwt/__pycache__/warnings.cpython-310.pyc,,
|
| 21 |
+
jwt/algorithms.py,sha256=cKr-XEioe0mBtqJMCaHEswqVOA1Z8Purt5Sb3Bi-5BE,30409
|
| 22 |
+
jwt/api_jwk.py,sha256=6F1r7rmm8V5qEnBKA_xMjS9R7VoANe1_BL1oD2FrAjE,4451
|
| 23 |
+
jwt/api_jws.py,sha256=aM8vzqQf6mRrAw7bRy-Moj_pjWsKSVQyYK896AfMjJU,11762
|
| 24 |
+
jwt/api_jwt.py,sha256=OGT4hok1l5A6FH_KdcrU5g6u6EQ8B7em0r9kGM9SYgA,14512
|
| 25 |
+
jwt/exceptions.py,sha256=bUIOJ-v9tjopTLS-FYOTc3kFx5WP5IZt7ksN_HE1G9Q,1211
|
| 26 |
+
jwt/help.py,sha256=vFdNzjQoAch04XCMYpCkyB2blaqHAGAqQrtf9nSPkdk,1808
|
| 27 |
+
jwt/jwk_set_cache.py,sha256=hBKmN-giU7-G37L_XKgc_OZu2ah4wdbj1ZNG_GkoSE8,959
|
| 28 |
+
jwt/jwks_client.py,sha256=p9b-IbQqo2tEge9Zit3oSPBFNePqwho96VLbnUrHUWs,4259
|
| 29 |
+
jwt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 30 |
+
jwt/types.py,sha256=VnhGv_VFu5a7_mrPoSCB7HaNLrJdhM8Sq1sSfEg0gLU,99
|
| 31 |
+
jwt/utils.py,sha256=hxOjvDBheBYhz-RIPiEz7Q88dSUSTMzEdKE_Ww2VdJw,3640
|
| 32 |
+
jwt/warnings.py,sha256=50XWOnyNsIaqzUJTk6XHNiIDykiL763GYA92MjTKmok,59
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (75.6.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
venv/lib/python3.10/site-packages/PyJWT-2.10.1.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
jwt
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding those notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 179 |
+
|
| 180 |
+
To apply the Apache License to your work, attach the following
|
| 181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 182 |
+
replaced with your own identifying information. (Don't include
|
| 183 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 184 |
+
comment syntax for the file format. We also recommend that a
|
| 185 |
+
file or class name and description of purpose be included on the
|
| 186 |
+
same "printed page" as the copyright notice for easier
|
| 187 |
+
identification within third-party archives.
|
| 188 |
+
|
| 189 |
+
Copyright [yyyy] [name of copyright owner]
|
| 190 |
+
|
| 191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 192 |
+
you may not use this file except in compliance with the License.
|
| 193 |
+
You may obtain a copy of the License at
|
| 194 |
+
|
| 195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 196 |
+
|
| 197 |
+
Unless required by applicable law or agreed to in writing, software
|
| 198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 200 |
+
See the License for the specific language governing permissions and
|
| 201 |
+
limitations under the License.
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.2
|
| 2 |
+
Name: diffusers
|
| 3 |
+
Version: 0.34.0
|
| 4 |
+
Summary: State-of-the-art diffusion in PyTorch and JAX.
|
| 5 |
+
Home-page: https://github.com/huggingface/diffusers
|
| 6 |
+
Author: The Hugging Face team (past and future) with the help of all our contributors (https://github.com/huggingface/diffusers/graphs/contributors)
|
| 7 |
+
Author-email: diffusers@huggingface.co
|
| 8 |
+
License: Apache 2.0 License
|
| 9 |
+
Keywords: deep learning diffusion jax pytorch stable diffusion audioldm
|
| 10 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 11 |
+
Classifier: Intended Audience :: Developers
|
| 12 |
+
Classifier: Intended Audience :: Education
|
| 13 |
+
Classifier: Intended Audience :: Science/Research
|
| 14 |
+
Classifier: License :: OSI Approved :: Apache Software License
|
| 15 |
+
Classifier: Operating System :: OS Independent
|
| 16 |
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
| 17 |
+
Classifier: Programming Language :: Python :: 3
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 21 |
+
Requires-Python: >=3.8.0
|
| 22 |
+
Description-Content-Type: text/markdown
|
| 23 |
+
License-File: LICENSE
|
| 24 |
+
Requires-Dist: importlib_metadata
|
| 25 |
+
Requires-Dist: filelock
|
| 26 |
+
Requires-Dist: huggingface-hub>=0.27.0
|
| 27 |
+
Requires-Dist: numpy
|
| 28 |
+
Requires-Dist: regex!=2019.12.17
|
| 29 |
+
Requires-Dist: requests
|
| 30 |
+
Requires-Dist: safetensors>=0.3.1
|
| 31 |
+
Requires-Dist: Pillow
|
| 32 |
+
Provides-Extra: quality
|
| 33 |
+
Requires-Dist: urllib3<=2.0.0; extra == "quality"
|
| 34 |
+
Requires-Dist: isort>=5.5.4; extra == "quality"
|
| 35 |
+
Requires-Dist: ruff==0.9.10; extra == "quality"
|
| 36 |
+
Requires-Dist: hf-doc-builder>=0.3.0; extra == "quality"
|
| 37 |
+
Provides-Extra: docs
|
| 38 |
+
Requires-Dist: hf-doc-builder>=0.3.0; extra == "docs"
|
| 39 |
+
Provides-Extra: training
|
| 40 |
+
Requires-Dist: accelerate>=0.31.0; extra == "training"
|
| 41 |
+
Requires-Dist: datasets; extra == "training"
|
| 42 |
+
Requires-Dist: protobuf<4,>=3.20.3; extra == "training"
|
| 43 |
+
Requires-Dist: tensorboard; extra == "training"
|
| 44 |
+
Requires-Dist: Jinja2; extra == "training"
|
| 45 |
+
Requires-Dist: peft>=0.15.0; extra == "training"
|
| 46 |
+
Provides-Extra: test
|
| 47 |
+
Requires-Dist: compel==0.1.8; extra == "test"
|
| 48 |
+
Requires-Dist: GitPython<3.1.19; extra == "test"
|
| 49 |
+
Requires-Dist: datasets; extra == "test"
|
| 50 |
+
Requires-Dist: Jinja2; extra == "test"
|
| 51 |
+
Requires-Dist: invisible-watermark>=0.2.0; extra == "test"
|
| 52 |
+
Requires-Dist: k-diffusion>=0.0.12; extra == "test"
|
| 53 |
+
Requires-Dist: librosa; extra == "test"
|
| 54 |
+
Requires-Dist: parameterized; extra == "test"
|
| 55 |
+
Requires-Dist: pytest; extra == "test"
|
| 56 |
+
Requires-Dist: pytest-timeout; extra == "test"
|
| 57 |
+
Requires-Dist: pytest-xdist; extra == "test"
|
| 58 |
+
Requires-Dist: requests-mock==1.10.0; extra == "test"
|
| 59 |
+
Requires-Dist: safetensors>=0.3.1; extra == "test"
|
| 60 |
+
Requires-Dist: sentencepiece!=0.1.92,>=0.1.91; extra == "test"
|
| 61 |
+
Requires-Dist: scipy; extra == "test"
|
| 62 |
+
Requires-Dist: tiktoken>=0.7.0; extra == "test"
|
| 63 |
+
Requires-Dist: torchvision; extra == "test"
|
| 64 |
+
Requires-Dist: transformers>=4.41.2; extra == "test"
|
| 65 |
+
Requires-Dist: phonemizer; extra == "test"
|
| 66 |
+
Provides-Extra: torch
|
| 67 |
+
Requires-Dist: torch>=1.4; extra == "torch"
|
| 68 |
+
Requires-Dist: accelerate>=0.31.0; extra == "torch"
|
| 69 |
+
Provides-Extra: bitsandbytes
|
| 70 |
+
Requires-Dist: bitsandbytes>=0.43.3; extra == "bitsandbytes"
|
| 71 |
+
Requires-Dist: accelerate>=0.31.0; extra == "bitsandbytes"
|
| 72 |
+
Provides-Extra: gguf
|
| 73 |
+
Requires-Dist: gguf>=0.10.0; extra == "gguf"
|
| 74 |
+
Requires-Dist: accelerate>=0.31.0; extra == "gguf"
|
| 75 |
+
Provides-Extra: optimum-quanto
|
| 76 |
+
Requires-Dist: optimum_quanto>=0.2.6; extra == "optimum-quanto"
|
| 77 |
+
Requires-Dist: accelerate>=0.31.0; extra == "optimum-quanto"
|
| 78 |
+
Provides-Extra: torchao
|
| 79 |
+
Requires-Dist: torchao>=0.7.0; extra == "torchao"
|
| 80 |
+
Requires-Dist: accelerate>=0.31.0; extra == "torchao"
|
| 81 |
+
Provides-Extra: flax
|
| 82 |
+
Requires-Dist: jax>=0.4.1; extra == "flax"
|
| 83 |
+
Requires-Dist: jaxlib>=0.4.1; extra == "flax"
|
| 84 |
+
Requires-Dist: flax>=0.4.1; extra == "flax"
|
| 85 |
+
Provides-Extra: dev
|
| 86 |
+
Requires-Dist: urllib3<=2.0.0; extra == "dev"
|
| 87 |
+
Requires-Dist: isort>=5.5.4; extra == "dev"
|
| 88 |
+
Requires-Dist: ruff==0.9.10; extra == "dev"
|
| 89 |
+
Requires-Dist: hf-doc-builder>=0.3.0; extra == "dev"
|
| 90 |
+
Requires-Dist: compel==0.1.8; extra == "dev"
|
| 91 |
+
Requires-Dist: GitPython<3.1.19; extra == "dev"
|
| 92 |
+
Requires-Dist: datasets; extra == "dev"
|
| 93 |
+
Requires-Dist: Jinja2; extra == "dev"
|
| 94 |
+
Requires-Dist: invisible-watermark>=0.2.0; extra == "dev"
|
| 95 |
+
Requires-Dist: k-diffusion>=0.0.12; extra == "dev"
|
| 96 |
+
Requires-Dist: librosa; extra == "dev"
|
| 97 |
+
Requires-Dist: parameterized; extra == "dev"
|
| 98 |
+
Requires-Dist: pytest; extra == "dev"
|
| 99 |
+
Requires-Dist: pytest-timeout; extra == "dev"
|
| 100 |
+
Requires-Dist: pytest-xdist; extra == "dev"
|
| 101 |
+
Requires-Dist: requests-mock==1.10.0; extra == "dev"
|
| 102 |
+
Requires-Dist: safetensors>=0.3.1; extra == "dev"
|
| 103 |
+
Requires-Dist: sentencepiece!=0.1.92,>=0.1.91; extra == "dev"
|
| 104 |
+
Requires-Dist: scipy; extra == "dev"
|
| 105 |
+
Requires-Dist: tiktoken>=0.7.0; extra == "dev"
|
| 106 |
+
Requires-Dist: torchvision; extra == "dev"
|
| 107 |
+
Requires-Dist: transformers>=4.41.2; extra == "dev"
|
| 108 |
+
Requires-Dist: phonemizer; extra == "dev"
|
| 109 |
+
Requires-Dist: accelerate>=0.31.0; extra == "dev"
|
| 110 |
+
Requires-Dist: datasets; extra == "dev"
|
| 111 |
+
Requires-Dist: protobuf<4,>=3.20.3; extra == "dev"
|
| 112 |
+
Requires-Dist: tensorboard; extra == "dev"
|
| 113 |
+
Requires-Dist: Jinja2; extra == "dev"
|
| 114 |
+
Requires-Dist: peft>=0.15.0; extra == "dev"
|
| 115 |
+
Requires-Dist: hf-doc-builder>=0.3.0; extra == "dev"
|
| 116 |
+
Requires-Dist: torch>=1.4; extra == "dev"
|
| 117 |
+
Requires-Dist: accelerate>=0.31.0; extra == "dev"
|
| 118 |
+
Requires-Dist: jax>=0.4.1; extra == "dev"
|
| 119 |
+
Requires-Dist: jaxlib>=0.4.1; extra == "dev"
|
| 120 |
+
Requires-Dist: flax>=0.4.1; extra == "dev"
|
| 121 |
+
Dynamic: author
|
| 122 |
+
Dynamic: author-email
|
| 123 |
+
Dynamic: classifier
|
| 124 |
+
Dynamic: description
|
| 125 |
+
Dynamic: description-content-type
|
| 126 |
+
Dynamic: home-page
|
| 127 |
+
Dynamic: keywords
|
| 128 |
+
Dynamic: license
|
| 129 |
+
Dynamic: provides-extra
|
| 130 |
+
Dynamic: requires-dist
|
| 131 |
+
Dynamic: requires-python
|
| 132 |
+
Dynamic: summary
|
| 133 |
+
|
| 134 |
+
<!---
|
| 135 |
+
Copyright 2022 - The HuggingFace Team. All rights reserved.
|
| 136 |
+
|
| 137 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 138 |
+
you may not use this file except in compliance with the License.
|
| 139 |
+
You may obtain a copy of the License at
|
| 140 |
+
|
| 141 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 142 |
+
|
| 143 |
+
Unless required by applicable law or agreed to in writing, software
|
| 144 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 145 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 146 |
+
See the License for the specific language governing permissions and
|
| 147 |
+
limitations under the License.
|
| 148 |
+
-->
|
| 149 |
+
|
| 150 |
+
<p align="center">
|
| 151 |
+
<br>
|
| 152 |
+
<img src="https://raw.githubusercontent.com/huggingface/diffusers/main/docs/source/en/imgs/diffusers_library.jpg" width="400"/>
|
| 153 |
+
<br>
|
| 154 |
+
<p>
|
| 155 |
+
<p align="center">
|
| 156 |
+
<a href="https://github.com/huggingface/diffusers/blob/main/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/huggingface/datasets.svg?color=blue"></a>
|
| 157 |
+
<a href="https://github.com/huggingface/diffusers/releases"><img alt="GitHub release" src="https://img.shields.io/github/release/huggingface/diffusers.svg"></a>
|
| 158 |
+
<a href="https://pepy.tech/project/diffusers"><img alt="GitHub release" src="https://static.pepy.tech/badge/diffusers/month"></a>
|
| 159 |
+
<a href="CODE_OF_CONDUCT.md"><img alt="Contributor Covenant" src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg"></a>
|
| 160 |
+
<a href="https://twitter.com/diffuserslib"><img alt="X account" src="https://img.shields.io/twitter/url/https/twitter.com/diffuserslib.svg?style=social&label=Follow%20%40diffuserslib"></a>
|
| 161 |
+
</p>
|
| 162 |
+
|
| 163 |
+
🤗 Diffusers is the go-to library for state-of-the-art pretrained diffusion models for generating images, audio, and even 3D structures of molecules. Whether you're looking for a simple inference solution or training your own diffusion models, 🤗 Diffusers is a modular toolbox that supports both. Our library is designed with a focus on [usability over performance](https://huggingface.co/docs/diffusers/conceptual/philosophy#usability-over-performance), [simple over easy](https://huggingface.co/docs/diffusers/conceptual/philosophy#simple-over-easy), and [customizability over abstractions](https://huggingface.co/docs/diffusers/conceptual/philosophy#tweakable-contributorfriendly-over-abstraction).
|
| 164 |
+
|
| 165 |
+
🤗 Diffusers offers three core components:
|
| 166 |
+
|
| 167 |
+
- State-of-the-art [diffusion pipelines](https://huggingface.co/docs/diffusers/api/pipelines/overview) that can be run in inference with just a few lines of code.
|
| 168 |
+
- Interchangeable noise [schedulers](https://huggingface.co/docs/diffusers/api/schedulers/overview) for different diffusion speeds and output quality.
|
| 169 |
+
- Pretrained [models](https://huggingface.co/docs/diffusers/api/models/overview) that can be used as building blocks, and combined with schedulers, for creating your own end-to-end diffusion systems.
|
| 170 |
+
|
| 171 |
+
## Installation
|
| 172 |
+
|
| 173 |
+
We recommend installing 🤗 Diffusers in a virtual environment from PyPI or Conda. For more details about installing [PyTorch](https://pytorch.org/get-started/locally/) and [Flax](https://flax.readthedocs.io/en/latest/#installation), please refer to their official documentation.
|
| 174 |
+
|
| 175 |
+
### PyTorch
|
| 176 |
+
|
| 177 |
+
With `pip` (official package):
|
| 178 |
+
|
| 179 |
+
```bash
|
| 180 |
+
pip install --upgrade diffusers[torch]
|
| 181 |
+
```
|
| 182 |
+
|
| 183 |
+
With `conda` (maintained by the community):
|
| 184 |
+
|
| 185 |
+
```sh
|
| 186 |
+
conda install -c conda-forge diffusers
|
| 187 |
+
```
|
| 188 |
+
|
| 189 |
+
### Flax
|
| 190 |
+
|
| 191 |
+
With `pip` (official package):
|
| 192 |
+
|
| 193 |
+
```bash
|
| 194 |
+
pip install --upgrade diffusers[flax]
|
| 195 |
+
```
|
| 196 |
+
|
| 197 |
+
### Apple Silicon (M1/M2) support
|
| 198 |
+
|
| 199 |
+
Please refer to the [How to use Stable Diffusion in Apple Silicon](https://huggingface.co/docs/diffusers/optimization/mps) guide.
|
| 200 |
+
|
| 201 |
+
## Quickstart
|
| 202 |
+
|
| 203 |
+
Generating outputs is super easy with 🤗 Diffusers. To generate an image from text, use the `from_pretrained` method to load any pretrained diffusion model (browse the [Hub](https://huggingface.co/models?library=diffusers&sort=downloads) for 30,000+ checkpoints):
|
| 204 |
+
|
| 205 |
+
```python
|
| 206 |
+
from diffusers import DiffusionPipeline
|
| 207 |
+
import torch
|
| 208 |
+
|
| 209 |
+
pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16)
|
| 210 |
+
pipeline.to("cuda")
|
| 211 |
+
pipeline("An image of a squirrel in Picasso style").images[0]
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
You can also dig into the models and schedulers toolbox to build your own diffusion system:
|
| 215 |
+
|
| 216 |
+
```python
|
| 217 |
+
from diffusers import DDPMScheduler, UNet2DModel
|
| 218 |
+
from PIL import Image
|
| 219 |
+
import torch
|
| 220 |
+
|
| 221 |
+
scheduler = DDPMScheduler.from_pretrained("google/ddpm-cat-256")
|
| 222 |
+
model = UNet2DModel.from_pretrained("google/ddpm-cat-256").to("cuda")
|
| 223 |
+
scheduler.set_timesteps(50)
|
| 224 |
+
|
| 225 |
+
sample_size = model.config.sample_size
|
| 226 |
+
noise = torch.randn((1, 3, sample_size, sample_size), device="cuda")
|
| 227 |
+
input = noise
|
| 228 |
+
|
| 229 |
+
for t in scheduler.timesteps:
|
| 230 |
+
with torch.no_grad():
|
| 231 |
+
noisy_residual = model(input, t).sample
|
| 232 |
+
prev_noisy_sample = scheduler.step(noisy_residual, t, input).prev_sample
|
| 233 |
+
input = prev_noisy_sample
|
| 234 |
+
|
| 235 |
+
image = (input / 2 + 0.5).clamp(0, 1)
|
| 236 |
+
image = image.cpu().permute(0, 2, 3, 1).numpy()[0]
|
| 237 |
+
image = Image.fromarray((image * 255).round().astype("uint8"))
|
| 238 |
+
image
|
| 239 |
+
```
|
| 240 |
+
|
| 241 |
+
Check out the [Quickstart](https://huggingface.co/docs/diffusers/quicktour) to launch your diffusion journey today!
|
| 242 |
+
|
| 243 |
+
## How to navigate the documentation
|
| 244 |
+
|
| 245 |
+
| **Documentation** | **What can I learn?** |
|
| 246 |
+
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| 247 |
+
| [Tutorial](https://huggingface.co/docs/diffusers/tutorials/tutorial_overview) | A basic crash course for learning how to use the library's most important features like using models and schedulers to build your own diffusion system, and training your own diffusion model. |
|
| 248 |
+
| [Loading](https://huggingface.co/docs/diffusers/using-diffusers/loading) | Guides for how to load and configure all the components (pipelines, models, and schedulers) of the library, as well as how to use different schedulers. |
|
| 249 |
+
| [Pipelines for inference](https://huggingface.co/docs/diffusers/using-diffusers/overview_techniques) | Guides for how to use pipelines for different inference tasks, batched generation, controlling generated outputs and randomness, and how to contribute a pipeline to the library. |
|
| 250 |
+
| [Optimization](https://huggingface.co/docs/diffusers/optimization/fp16) | Guides for how to optimize your diffusion model to run faster and consume less memory. |
|
| 251 |
+
| [Training](https://huggingface.co/docs/diffusers/training/overview) | Guides for how to train a diffusion model for different tasks with different training techniques. |
|
| 252 |
+
## Contribution
|
| 253 |
+
|
| 254 |
+
We ❤️ contributions from the open-source community!
|
| 255 |
+
If you want to contribute to this library, please check out our [Contribution guide](https://github.com/huggingface/diffusers/blob/main/CONTRIBUTING.md).
|
| 256 |
+
You can look out for [issues](https://github.com/huggingface/diffusers/issues) you'd like to tackle to contribute to the library.
|
| 257 |
+
- See [Good first issues](https://github.com/huggingface/diffusers/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) for general opportunities to contribute
|
| 258 |
+
- See [New model/pipeline](https://github.com/huggingface/diffusers/issues?q=is%3Aopen+is%3Aissue+label%3A%22New+pipeline%2Fmodel%22) to contribute exciting new diffusion models / diffusion pipelines
|
| 259 |
+
- See [New scheduler](https://github.com/huggingface/diffusers/issues?q=is%3Aopen+is%3Aissue+label%3A%22New+scheduler%22)
|
| 260 |
+
|
| 261 |
+
Also, say 👋 in our public Discord channel <a href="https://discord.gg/G7tWnz98XR"><img alt="Join us on Discord" src="https://img.shields.io/discord/823813159592001537?color=5865F2&logo=discord&logoColor=white"></a>. We discuss the hottest trends about diffusion models, help each other with contributions, personal projects or just hang out ☕.
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
## Popular Tasks & Pipelines
|
| 265 |
+
|
| 266 |
+
<table>
|
| 267 |
+
<tr>
|
| 268 |
+
<th>Task</th>
|
| 269 |
+
<th>Pipeline</th>
|
| 270 |
+
<th>🤗 Hub</th>
|
| 271 |
+
</tr>
|
| 272 |
+
<tr style="border-top: 2px solid black">
|
| 273 |
+
<td>Unconditional Image Generation</td>
|
| 274 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/ddpm"> DDPM </a></td>
|
| 275 |
+
<td><a href="https://huggingface.co/google/ddpm-ema-church-256"> google/ddpm-ema-church-256 </a></td>
|
| 276 |
+
</tr>
|
| 277 |
+
<tr style="border-top: 2px solid black">
|
| 278 |
+
<td>Text-to-Image</td>
|
| 279 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/text2img">Stable Diffusion Text-to-Image</a></td>
|
| 280 |
+
<td><a href="https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5"> stable-diffusion-v1-5/stable-diffusion-v1-5 </a></td>
|
| 281 |
+
</tr>
|
| 282 |
+
<tr>
|
| 283 |
+
<td>Text-to-Image</td>
|
| 284 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/unclip">unCLIP</a></td>
|
| 285 |
+
<td><a href="https://huggingface.co/kakaobrain/karlo-v1-alpha"> kakaobrain/karlo-v1-alpha </a></td>
|
| 286 |
+
</tr>
|
| 287 |
+
<tr>
|
| 288 |
+
<td>Text-to-Image</td>
|
| 289 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/deepfloyd_if">DeepFloyd IF</a></td>
|
| 290 |
+
<td><a href="https://huggingface.co/DeepFloyd/IF-I-XL-v1.0"> DeepFloyd/IF-I-XL-v1.0 </a></td>
|
| 291 |
+
</tr>
|
| 292 |
+
<tr>
|
| 293 |
+
<td>Text-to-Image</td>
|
| 294 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/kandinsky">Kandinsky</a></td>
|
| 295 |
+
<td><a href="https://huggingface.co/kandinsky-community/kandinsky-2-2-decoder"> kandinsky-community/kandinsky-2-2-decoder </a></td>
|
| 296 |
+
</tr>
|
| 297 |
+
<tr style="border-top: 2px solid black">
|
| 298 |
+
<td>Text-guided Image-to-Image</td>
|
| 299 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/controlnet">ControlNet</a></td>
|
| 300 |
+
<td><a href="https://huggingface.co/lllyasviel/sd-controlnet-canny"> lllyasviel/sd-controlnet-canny </a></td>
|
| 301 |
+
</tr>
|
| 302 |
+
<tr>
|
| 303 |
+
<td>Text-guided Image-to-Image</td>
|
| 304 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/pix2pix">InstructPix2Pix</a></td>
|
| 305 |
+
<td><a href="https://huggingface.co/timbrooks/instruct-pix2pix"> timbrooks/instruct-pix2pix </a></td>
|
| 306 |
+
</tr>
|
| 307 |
+
<tr>
|
| 308 |
+
<td>Text-guided Image-to-Image</td>
|
| 309 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/img2img">Stable Diffusion Image-to-Image</a></td>
|
| 310 |
+
<td><a href="https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5"> stable-diffusion-v1-5/stable-diffusion-v1-5 </a></td>
|
| 311 |
+
</tr>
|
| 312 |
+
<tr style="border-top: 2px solid black">
|
| 313 |
+
<td>Text-guided Image Inpainting</td>
|
| 314 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/inpaint">Stable Diffusion Inpainting</a></td>
|
| 315 |
+
<td><a href="https://huggingface.co/runwayml/stable-diffusion-inpainting"> runwayml/stable-diffusion-inpainting </a></td>
|
| 316 |
+
</tr>
|
| 317 |
+
<tr style="border-top: 2px solid black">
|
| 318 |
+
<td>Image Variation</td>
|
| 319 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/image_variation">Stable Diffusion Image Variation</a></td>
|
| 320 |
+
<td><a href="https://huggingface.co/lambdalabs/sd-image-variations-diffusers"> lambdalabs/sd-image-variations-diffusers </a></td>
|
| 321 |
+
</tr>
|
| 322 |
+
<tr style="border-top: 2px solid black">
|
| 323 |
+
<td>Super Resolution</td>
|
| 324 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/upscale">Stable Diffusion Upscale</a></td>
|
| 325 |
+
<td><a href="https://huggingface.co/stabilityai/stable-diffusion-x4-upscaler"> stabilityai/stable-diffusion-x4-upscaler </a></td>
|
| 326 |
+
</tr>
|
| 327 |
+
<tr>
|
| 328 |
+
<td>Super Resolution</td>
|
| 329 |
+
<td><a href="https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/latent_upscale">Stable Diffusion Latent Upscale</a></td>
|
| 330 |
+
<td><a href="https://huggingface.co/stabilityai/sd-x2-latent-upscaler"> stabilityai/sd-x2-latent-upscaler </a></td>
|
| 331 |
+
</tr>
|
| 332 |
+
</table>
|
| 333 |
+
|
| 334 |
+
## Popular libraries using 🧨 Diffusers
|
| 335 |
+
|
| 336 |
+
- https://github.com/microsoft/TaskMatrix
|
| 337 |
+
- https://github.com/invoke-ai/InvokeAI
|
| 338 |
+
- https://github.com/InstantID/InstantID
|
| 339 |
+
- https://github.com/apple/ml-stable-diffusion
|
| 340 |
+
- https://github.com/Sanster/lama-cleaner
|
| 341 |
+
- https://github.com/IDEA-Research/Grounded-Segment-Anything
|
| 342 |
+
- https://github.com/ashawkey/stable-dreamfusion
|
| 343 |
+
- https://github.com/deep-floyd/IF
|
| 344 |
+
- https://github.com/bentoml/BentoML
|
| 345 |
+
- https://github.com/bmaltais/kohya_ss
|
| 346 |
+
- +14,000 other amazing GitHub repositories 💪
|
| 347 |
+
|
| 348 |
+
Thank you for using us ❤️.
|
| 349 |
+
|
| 350 |
+
## Credits
|
| 351 |
+
|
| 352 |
+
This library concretizes previous work by many different authors and would not have been possible without their great research and implementations. We'd like to thank, in particular, the following implementations which have helped us in our development and without which the API could not have been as polished today:
|
| 353 |
+
|
| 354 |
+
- @CompVis' latent diffusion models library, available [here](https://github.com/CompVis/latent-diffusion)
|
| 355 |
+
- @hojonathanho original DDPM implementation, available [here](https://github.com/hojonathanho/diffusion) as well as the extremely useful translation into PyTorch by @pesser, available [here](https://github.com/pesser/pytorch_diffusion)
|
| 356 |
+
- @ermongroup's DDIM implementation, available [here](https://github.com/ermongroup/ddim)
|
| 357 |
+
- @yang-song's Score-VE and Score-VP implementations, available [here](https://github.com/yang-song/score_sde_pytorch)
|
| 358 |
+
|
| 359 |
+
We also want to thank @heejkoo for the very helpful overview of papers, code and resources on diffusion models, available [here](https://github.com/heejkoo/Awesome-Diffusion-Models) as well as @crowsonkb and @rromb for useful discussions and insights.
|
| 360 |
+
|
| 361 |
+
## Citation
|
| 362 |
+
|
| 363 |
+
```bibtex
|
| 364 |
+
@misc{von-platen-etal-2022-diffusers,
|
| 365 |
+
author = {Patrick von Platen and Suraj Patil and Anton Lozhkov and Pedro Cuenca and Nathan Lambert and Kashif Rasul and Mishig Davaadorj and Dhruv Nair and Sayak Paul and William Berman and Yiyi Xu and Steven Liu and Thomas Wolf},
|
| 366 |
+
title = {Diffusers: State-of-the-art diffusion models},
|
| 367 |
+
year = {2022},
|
| 368 |
+
publisher = {GitHub},
|
| 369 |
+
journal = {GitHub repository},
|
| 370 |
+
howpublished = {\url{https://github.com/huggingface/diffusers}}
|
| 371 |
+
}
|
| 372 |
+
```
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/RECORD
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/REQUESTED
ADDED
|
File without changes
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (75.8.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/entry_points.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[console_scripts]
|
| 2 |
+
diffusers-cli = diffusers.commands.diffusers_cli:main
|
venv/lib/python3.10/site-packages/diffusers-0.34.0.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
diffusers
|
venv/lib/python3.10/site-packages/diffusers/__init__.py
ADDED
|
@@ -0,0 +1,1244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__version__ = "0.34.0"
|
| 2 |
+
|
| 3 |
+
from typing import TYPE_CHECKING
|
| 4 |
+
|
| 5 |
+
from .utils import (
|
| 6 |
+
DIFFUSERS_SLOW_IMPORT,
|
| 7 |
+
OptionalDependencyNotAvailable,
|
| 8 |
+
_LazyModule,
|
| 9 |
+
is_accelerate_available,
|
| 10 |
+
is_bitsandbytes_available,
|
| 11 |
+
is_flax_available,
|
| 12 |
+
is_gguf_available,
|
| 13 |
+
is_k_diffusion_available,
|
| 14 |
+
is_librosa_available,
|
| 15 |
+
is_note_seq_available,
|
| 16 |
+
is_onnx_available,
|
| 17 |
+
is_opencv_available,
|
| 18 |
+
is_optimum_quanto_available,
|
| 19 |
+
is_scipy_available,
|
| 20 |
+
is_sentencepiece_available,
|
| 21 |
+
is_torch_available,
|
| 22 |
+
is_torchao_available,
|
| 23 |
+
is_torchsde_available,
|
| 24 |
+
is_transformers_available,
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
# Lazy Import based on
|
| 29 |
+
# https://github.com/huggingface/transformers/blob/main/src/transformers/__init__.py
|
| 30 |
+
|
| 31 |
+
# When adding a new object to this init, please add it to `_import_structure`. The `_import_structure` is a dictionary submodule to list of object names,
|
| 32 |
+
# and is used to defer the actual importing for when the objects are requested.
|
| 33 |
+
# This way `import diffusers` provides the names in the namespace without actually importing anything (and especially none of the backends).
|
| 34 |
+
|
| 35 |
+
_import_structure = {
|
| 36 |
+
"configuration_utils": ["ConfigMixin"],
|
| 37 |
+
"hooks": [],
|
| 38 |
+
"loaders": ["FromOriginalModelMixin"],
|
| 39 |
+
"models": [],
|
| 40 |
+
"pipelines": [],
|
| 41 |
+
"quantizers.quantization_config": [],
|
| 42 |
+
"schedulers": [],
|
| 43 |
+
"utils": [
|
| 44 |
+
"OptionalDependencyNotAvailable",
|
| 45 |
+
"is_flax_available",
|
| 46 |
+
"is_inflect_available",
|
| 47 |
+
"is_invisible_watermark_available",
|
| 48 |
+
"is_k_diffusion_available",
|
| 49 |
+
"is_k_diffusion_version",
|
| 50 |
+
"is_librosa_available",
|
| 51 |
+
"is_note_seq_available",
|
| 52 |
+
"is_onnx_available",
|
| 53 |
+
"is_scipy_available",
|
| 54 |
+
"is_torch_available",
|
| 55 |
+
"is_torchsde_available",
|
| 56 |
+
"is_transformers_available",
|
| 57 |
+
"is_transformers_version",
|
| 58 |
+
"is_unidecode_available",
|
| 59 |
+
"logging",
|
| 60 |
+
],
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
try:
|
| 64 |
+
if not is_torch_available() and not is_accelerate_available() and not is_bitsandbytes_available():
|
| 65 |
+
raise OptionalDependencyNotAvailable()
|
| 66 |
+
except OptionalDependencyNotAvailable:
|
| 67 |
+
from .utils import dummy_bitsandbytes_objects
|
| 68 |
+
|
| 69 |
+
_import_structure["utils.dummy_bitsandbytes_objects"] = [
|
| 70 |
+
name for name in dir(dummy_bitsandbytes_objects) if not name.startswith("_")
|
| 71 |
+
]
|
| 72 |
+
else:
|
| 73 |
+
_import_structure["quantizers.quantization_config"].append("BitsAndBytesConfig")
|
| 74 |
+
|
| 75 |
+
try:
|
| 76 |
+
if not is_torch_available() and not is_accelerate_available() and not is_gguf_available():
|
| 77 |
+
raise OptionalDependencyNotAvailable()
|
| 78 |
+
except OptionalDependencyNotAvailable:
|
| 79 |
+
from .utils import dummy_gguf_objects
|
| 80 |
+
|
| 81 |
+
_import_structure["utils.dummy_gguf_objects"] = [
|
| 82 |
+
name for name in dir(dummy_gguf_objects) if not name.startswith("_")
|
| 83 |
+
]
|
| 84 |
+
else:
|
| 85 |
+
_import_structure["quantizers.quantization_config"].append("GGUFQuantizationConfig")
|
| 86 |
+
|
| 87 |
+
try:
|
| 88 |
+
if not is_torch_available() and not is_accelerate_available() and not is_torchao_available():
|
| 89 |
+
raise OptionalDependencyNotAvailable()
|
| 90 |
+
except OptionalDependencyNotAvailable:
|
| 91 |
+
from .utils import dummy_torchao_objects
|
| 92 |
+
|
| 93 |
+
_import_structure["utils.dummy_torchao_objects"] = [
|
| 94 |
+
name for name in dir(dummy_torchao_objects) if not name.startswith("_")
|
| 95 |
+
]
|
| 96 |
+
else:
|
| 97 |
+
_import_structure["quantizers.quantization_config"].append("TorchAoConfig")
|
| 98 |
+
|
| 99 |
+
try:
|
| 100 |
+
if not is_torch_available() and not is_accelerate_available() and not is_optimum_quanto_available():
|
| 101 |
+
raise OptionalDependencyNotAvailable()
|
| 102 |
+
except OptionalDependencyNotAvailable:
|
| 103 |
+
from .utils import dummy_optimum_quanto_objects
|
| 104 |
+
|
| 105 |
+
_import_structure["utils.dummy_optimum_quanto_objects"] = [
|
| 106 |
+
name for name in dir(dummy_optimum_quanto_objects) if not name.startswith("_")
|
| 107 |
+
]
|
| 108 |
+
else:
|
| 109 |
+
_import_structure["quantizers.quantization_config"].append("QuantoConfig")
|
| 110 |
+
|
| 111 |
+
try:
|
| 112 |
+
if not is_onnx_available():
|
| 113 |
+
raise OptionalDependencyNotAvailable()
|
| 114 |
+
except OptionalDependencyNotAvailable:
|
| 115 |
+
from .utils import dummy_onnx_objects # noqa F403
|
| 116 |
+
|
| 117 |
+
_import_structure["utils.dummy_onnx_objects"] = [
|
| 118 |
+
name for name in dir(dummy_onnx_objects) if not name.startswith("_")
|
| 119 |
+
]
|
| 120 |
+
|
| 121 |
+
else:
|
| 122 |
+
_import_structure["pipelines"].extend(["OnnxRuntimeModel"])
|
| 123 |
+
|
| 124 |
+
try:
|
| 125 |
+
if not is_torch_available():
|
| 126 |
+
raise OptionalDependencyNotAvailable()
|
| 127 |
+
except OptionalDependencyNotAvailable:
|
| 128 |
+
from .utils import dummy_pt_objects # noqa F403
|
| 129 |
+
|
| 130 |
+
_import_structure["utils.dummy_pt_objects"] = [name for name in dir(dummy_pt_objects) if not name.startswith("_")]
|
| 131 |
+
|
| 132 |
+
else:
|
| 133 |
+
_import_structure["hooks"].extend(
|
| 134 |
+
[
|
| 135 |
+
"FasterCacheConfig",
|
| 136 |
+
"HookRegistry",
|
| 137 |
+
"PyramidAttentionBroadcastConfig",
|
| 138 |
+
"apply_faster_cache",
|
| 139 |
+
"apply_pyramid_attention_broadcast",
|
| 140 |
+
]
|
| 141 |
+
)
|
| 142 |
+
_import_structure["models"].extend(
|
| 143 |
+
[
|
| 144 |
+
"AllegroTransformer3DModel",
|
| 145 |
+
"AsymmetricAutoencoderKL",
|
| 146 |
+
"AuraFlowTransformer2DModel",
|
| 147 |
+
"AutoencoderDC",
|
| 148 |
+
"AutoencoderKL",
|
| 149 |
+
"AutoencoderKLAllegro",
|
| 150 |
+
"AutoencoderKLCogVideoX",
|
| 151 |
+
"AutoencoderKLCosmos",
|
| 152 |
+
"AutoencoderKLHunyuanVideo",
|
| 153 |
+
"AutoencoderKLLTXVideo",
|
| 154 |
+
"AutoencoderKLMagvit",
|
| 155 |
+
"AutoencoderKLMochi",
|
| 156 |
+
"AutoencoderKLTemporalDecoder",
|
| 157 |
+
"AutoencoderKLWan",
|
| 158 |
+
"AutoencoderOobleck",
|
| 159 |
+
"AutoencoderTiny",
|
| 160 |
+
"AutoModel",
|
| 161 |
+
"CacheMixin",
|
| 162 |
+
"ChromaTransformer2DModel",
|
| 163 |
+
"CogVideoXTransformer3DModel",
|
| 164 |
+
"CogView3PlusTransformer2DModel",
|
| 165 |
+
"CogView4Transformer2DModel",
|
| 166 |
+
"ConsisIDTransformer3DModel",
|
| 167 |
+
"ConsistencyDecoderVAE",
|
| 168 |
+
"ControlNetModel",
|
| 169 |
+
"ControlNetUnionModel",
|
| 170 |
+
"ControlNetXSAdapter",
|
| 171 |
+
"CosmosTransformer3DModel",
|
| 172 |
+
"DiTTransformer2DModel",
|
| 173 |
+
"EasyAnimateTransformer3DModel",
|
| 174 |
+
"FluxControlNetModel",
|
| 175 |
+
"FluxMultiControlNetModel",
|
| 176 |
+
"FluxTransformer2DModel",
|
| 177 |
+
"HiDreamImageTransformer2DModel",
|
| 178 |
+
"HunyuanDiT2DControlNetModel",
|
| 179 |
+
"HunyuanDiT2DModel",
|
| 180 |
+
"HunyuanDiT2DMultiControlNetModel",
|
| 181 |
+
"HunyuanVideoFramepackTransformer3DModel",
|
| 182 |
+
"HunyuanVideoTransformer3DModel",
|
| 183 |
+
"I2VGenXLUNet",
|
| 184 |
+
"Kandinsky3UNet",
|
| 185 |
+
"LatteTransformer3DModel",
|
| 186 |
+
"LTXVideoTransformer3DModel",
|
| 187 |
+
"Lumina2Transformer2DModel",
|
| 188 |
+
"LuminaNextDiT2DModel",
|
| 189 |
+
"MochiTransformer3DModel",
|
| 190 |
+
"ModelMixin",
|
| 191 |
+
"MotionAdapter",
|
| 192 |
+
"MultiAdapter",
|
| 193 |
+
"MultiControlNetModel",
|
| 194 |
+
"OmniGenTransformer2DModel",
|
| 195 |
+
"PixArtTransformer2DModel",
|
| 196 |
+
"PriorTransformer",
|
| 197 |
+
"SanaControlNetModel",
|
| 198 |
+
"SanaTransformer2DModel",
|
| 199 |
+
"SD3ControlNetModel",
|
| 200 |
+
"SD3MultiControlNetModel",
|
| 201 |
+
"SD3Transformer2DModel",
|
| 202 |
+
"SparseControlNetModel",
|
| 203 |
+
"StableAudioDiTModel",
|
| 204 |
+
"StableCascadeUNet",
|
| 205 |
+
"T2IAdapter",
|
| 206 |
+
"T5FilmDecoder",
|
| 207 |
+
"Transformer2DModel",
|
| 208 |
+
"TransformerTemporalModel",
|
| 209 |
+
"UNet1DModel",
|
| 210 |
+
"UNet2DConditionModel",
|
| 211 |
+
"UNet2DModel",
|
| 212 |
+
"UNet3DConditionModel",
|
| 213 |
+
"UNetControlNetXSModel",
|
| 214 |
+
"UNetMotionModel",
|
| 215 |
+
"UNetSpatioTemporalConditionModel",
|
| 216 |
+
"UVit2DModel",
|
| 217 |
+
"VQModel",
|
| 218 |
+
"WanTransformer3DModel",
|
| 219 |
+
"WanVACETransformer3DModel",
|
| 220 |
+
]
|
| 221 |
+
)
|
| 222 |
+
_import_structure["optimization"] = [
|
| 223 |
+
"get_constant_schedule",
|
| 224 |
+
"get_constant_schedule_with_warmup",
|
| 225 |
+
"get_cosine_schedule_with_warmup",
|
| 226 |
+
"get_cosine_with_hard_restarts_schedule_with_warmup",
|
| 227 |
+
"get_linear_schedule_with_warmup",
|
| 228 |
+
"get_polynomial_decay_schedule_with_warmup",
|
| 229 |
+
"get_scheduler",
|
| 230 |
+
]
|
| 231 |
+
_import_structure["pipelines"].extend(
|
| 232 |
+
[
|
| 233 |
+
"AudioPipelineOutput",
|
| 234 |
+
"AutoPipelineForImage2Image",
|
| 235 |
+
"AutoPipelineForInpainting",
|
| 236 |
+
"AutoPipelineForText2Image",
|
| 237 |
+
"ConsistencyModelPipeline",
|
| 238 |
+
"DanceDiffusionPipeline",
|
| 239 |
+
"DDIMPipeline",
|
| 240 |
+
"DDPMPipeline",
|
| 241 |
+
"DiffusionPipeline",
|
| 242 |
+
"DiTPipeline",
|
| 243 |
+
"ImagePipelineOutput",
|
| 244 |
+
"KarrasVePipeline",
|
| 245 |
+
"LDMPipeline",
|
| 246 |
+
"LDMSuperResolutionPipeline",
|
| 247 |
+
"PNDMPipeline",
|
| 248 |
+
"RePaintPipeline",
|
| 249 |
+
"ScoreSdeVePipeline",
|
| 250 |
+
"StableDiffusionMixin",
|
| 251 |
+
]
|
| 252 |
+
)
|
| 253 |
+
_import_structure["quantizers"] = ["DiffusersQuantizer"]
|
| 254 |
+
_import_structure["schedulers"].extend(
|
| 255 |
+
[
|
| 256 |
+
"AmusedScheduler",
|
| 257 |
+
"CMStochasticIterativeScheduler",
|
| 258 |
+
"CogVideoXDDIMScheduler",
|
| 259 |
+
"CogVideoXDPMScheduler",
|
| 260 |
+
"DDIMInverseScheduler",
|
| 261 |
+
"DDIMParallelScheduler",
|
| 262 |
+
"DDIMScheduler",
|
| 263 |
+
"DDPMParallelScheduler",
|
| 264 |
+
"DDPMScheduler",
|
| 265 |
+
"DDPMWuerstchenScheduler",
|
| 266 |
+
"DEISMultistepScheduler",
|
| 267 |
+
"DPMSolverMultistepInverseScheduler",
|
| 268 |
+
"DPMSolverMultistepScheduler",
|
| 269 |
+
"DPMSolverSinglestepScheduler",
|
| 270 |
+
"EDMDPMSolverMultistepScheduler",
|
| 271 |
+
"EDMEulerScheduler",
|
| 272 |
+
"EulerAncestralDiscreteScheduler",
|
| 273 |
+
"EulerDiscreteScheduler",
|
| 274 |
+
"FlowMatchEulerDiscreteScheduler",
|
| 275 |
+
"FlowMatchHeunDiscreteScheduler",
|
| 276 |
+
"FlowMatchLCMScheduler",
|
| 277 |
+
"HeunDiscreteScheduler",
|
| 278 |
+
"IPNDMScheduler",
|
| 279 |
+
"KarrasVeScheduler",
|
| 280 |
+
"KDPM2AncestralDiscreteScheduler",
|
| 281 |
+
"KDPM2DiscreteScheduler",
|
| 282 |
+
"LCMScheduler",
|
| 283 |
+
"PNDMScheduler",
|
| 284 |
+
"RePaintScheduler",
|
| 285 |
+
"SASolverScheduler",
|
| 286 |
+
"SchedulerMixin",
|
| 287 |
+
"SCMScheduler",
|
| 288 |
+
"ScoreSdeVeScheduler",
|
| 289 |
+
"TCDScheduler",
|
| 290 |
+
"UnCLIPScheduler",
|
| 291 |
+
"UniPCMultistepScheduler",
|
| 292 |
+
"VQDiffusionScheduler",
|
| 293 |
+
]
|
| 294 |
+
)
|
| 295 |
+
_import_structure["training_utils"] = ["EMAModel"]
|
| 296 |
+
|
| 297 |
+
try:
|
| 298 |
+
if not (is_torch_available() and is_scipy_available()):
|
| 299 |
+
raise OptionalDependencyNotAvailable()
|
| 300 |
+
except OptionalDependencyNotAvailable:
|
| 301 |
+
from .utils import dummy_torch_and_scipy_objects # noqa F403
|
| 302 |
+
|
| 303 |
+
_import_structure["utils.dummy_torch_and_scipy_objects"] = [
|
| 304 |
+
name for name in dir(dummy_torch_and_scipy_objects) if not name.startswith("_")
|
| 305 |
+
]
|
| 306 |
+
|
| 307 |
+
else:
|
| 308 |
+
_import_structure["schedulers"].extend(["LMSDiscreteScheduler"])
|
| 309 |
+
|
| 310 |
+
try:
|
| 311 |
+
if not (is_torch_available() and is_torchsde_available()):
|
| 312 |
+
raise OptionalDependencyNotAvailable()
|
| 313 |
+
except OptionalDependencyNotAvailable:
|
| 314 |
+
from .utils import dummy_torch_and_torchsde_objects # noqa F403
|
| 315 |
+
|
| 316 |
+
_import_structure["utils.dummy_torch_and_torchsde_objects"] = [
|
| 317 |
+
name for name in dir(dummy_torch_and_torchsde_objects) if not name.startswith("_")
|
| 318 |
+
]
|
| 319 |
+
|
| 320 |
+
else:
|
| 321 |
+
_import_structure["schedulers"].extend(["CosineDPMSolverMultistepScheduler", "DPMSolverSDEScheduler"])
|
| 322 |
+
|
| 323 |
+
try:
|
| 324 |
+
if not (is_torch_available() and is_transformers_available()):
|
| 325 |
+
raise OptionalDependencyNotAvailable()
|
| 326 |
+
except OptionalDependencyNotAvailable:
|
| 327 |
+
from .utils import dummy_torch_and_transformers_objects # noqa F403
|
| 328 |
+
|
| 329 |
+
_import_structure["utils.dummy_torch_and_transformers_objects"] = [
|
| 330 |
+
name for name in dir(dummy_torch_and_transformers_objects) if not name.startswith("_")
|
| 331 |
+
]
|
| 332 |
+
|
| 333 |
+
else:
|
| 334 |
+
_import_structure["pipelines"].extend(
|
| 335 |
+
[
|
| 336 |
+
"AllegroPipeline",
|
| 337 |
+
"AltDiffusionImg2ImgPipeline",
|
| 338 |
+
"AltDiffusionPipeline",
|
| 339 |
+
"AmusedImg2ImgPipeline",
|
| 340 |
+
"AmusedInpaintPipeline",
|
| 341 |
+
"AmusedPipeline",
|
| 342 |
+
"AnimateDiffControlNetPipeline",
|
| 343 |
+
"AnimateDiffPAGPipeline",
|
| 344 |
+
"AnimateDiffPipeline",
|
| 345 |
+
"AnimateDiffSDXLPipeline",
|
| 346 |
+
"AnimateDiffSparseControlNetPipeline",
|
| 347 |
+
"AnimateDiffVideoToVideoControlNetPipeline",
|
| 348 |
+
"AnimateDiffVideoToVideoPipeline",
|
| 349 |
+
"AudioLDM2Pipeline",
|
| 350 |
+
"AudioLDM2ProjectionModel",
|
| 351 |
+
"AudioLDM2UNet2DConditionModel",
|
| 352 |
+
"AudioLDMPipeline",
|
| 353 |
+
"AuraFlowPipeline",
|
| 354 |
+
"BlipDiffusionControlNetPipeline",
|
| 355 |
+
"BlipDiffusionPipeline",
|
| 356 |
+
"ChromaImg2ImgPipeline",
|
| 357 |
+
"ChromaPipeline",
|
| 358 |
+
"CLIPImageProjection",
|
| 359 |
+
"CogVideoXFunControlPipeline",
|
| 360 |
+
"CogVideoXImageToVideoPipeline",
|
| 361 |
+
"CogVideoXPipeline",
|
| 362 |
+
"CogVideoXVideoToVideoPipeline",
|
| 363 |
+
"CogView3PlusPipeline",
|
| 364 |
+
"CogView4ControlPipeline",
|
| 365 |
+
"CogView4Pipeline",
|
| 366 |
+
"ConsisIDPipeline",
|
| 367 |
+
"Cosmos2TextToImagePipeline",
|
| 368 |
+
"Cosmos2VideoToWorldPipeline",
|
| 369 |
+
"CosmosTextToWorldPipeline",
|
| 370 |
+
"CosmosVideoToWorldPipeline",
|
| 371 |
+
"CycleDiffusionPipeline",
|
| 372 |
+
"EasyAnimateControlPipeline",
|
| 373 |
+
"EasyAnimateInpaintPipeline",
|
| 374 |
+
"EasyAnimatePipeline",
|
| 375 |
+
"FluxControlImg2ImgPipeline",
|
| 376 |
+
"FluxControlInpaintPipeline",
|
| 377 |
+
"FluxControlNetImg2ImgPipeline",
|
| 378 |
+
"FluxControlNetInpaintPipeline",
|
| 379 |
+
"FluxControlNetPipeline",
|
| 380 |
+
"FluxControlPipeline",
|
| 381 |
+
"FluxFillPipeline",
|
| 382 |
+
"FluxImg2ImgPipeline",
|
| 383 |
+
"FluxInpaintPipeline",
|
| 384 |
+
"FluxPipeline",
|
| 385 |
+
"FluxPriorReduxPipeline",
|
| 386 |
+
"HiDreamImagePipeline",
|
| 387 |
+
"HunyuanDiTControlNetPipeline",
|
| 388 |
+
"HunyuanDiTPAGPipeline",
|
| 389 |
+
"HunyuanDiTPipeline",
|
| 390 |
+
"HunyuanSkyreelsImageToVideoPipeline",
|
| 391 |
+
"HunyuanVideoFramepackPipeline",
|
| 392 |
+
"HunyuanVideoImageToVideoPipeline",
|
| 393 |
+
"HunyuanVideoPipeline",
|
| 394 |
+
"I2VGenXLPipeline",
|
| 395 |
+
"IFImg2ImgPipeline",
|
| 396 |
+
"IFImg2ImgSuperResolutionPipeline",
|
| 397 |
+
"IFInpaintingPipeline",
|
| 398 |
+
"IFInpaintingSuperResolutionPipeline",
|
| 399 |
+
"IFPipeline",
|
| 400 |
+
"IFSuperResolutionPipeline",
|
| 401 |
+
"ImageTextPipelineOutput",
|
| 402 |
+
"Kandinsky3Img2ImgPipeline",
|
| 403 |
+
"Kandinsky3Pipeline",
|
| 404 |
+
"KandinskyCombinedPipeline",
|
| 405 |
+
"KandinskyImg2ImgCombinedPipeline",
|
| 406 |
+
"KandinskyImg2ImgPipeline",
|
| 407 |
+
"KandinskyInpaintCombinedPipeline",
|
| 408 |
+
"KandinskyInpaintPipeline",
|
| 409 |
+
"KandinskyPipeline",
|
| 410 |
+
"KandinskyPriorPipeline",
|
| 411 |
+
"KandinskyV22CombinedPipeline",
|
| 412 |
+
"KandinskyV22ControlnetImg2ImgPipeline",
|
| 413 |
+
"KandinskyV22ControlnetPipeline",
|
| 414 |
+
"KandinskyV22Img2ImgCombinedPipeline",
|
| 415 |
+
"KandinskyV22Img2ImgPipeline",
|
| 416 |
+
"KandinskyV22InpaintCombinedPipeline",
|
| 417 |
+
"KandinskyV22InpaintPipeline",
|
| 418 |
+
"KandinskyV22Pipeline",
|
| 419 |
+
"KandinskyV22PriorEmb2EmbPipeline",
|
| 420 |
+
"KandinskyV22PriorPipeline",
|
| 421 |
+
"LatentConsistencyModelImg2ImgPipeline",
|
| 422 |
+
"LatentConsistencyModelPipeline",
|
| 423 |
+
"LattePipeline",
|
| 424 |
+
"LDMTextToImagePipeline",
|
| 425 |
+
"LEditsPPPipelineStableDiffusion",
|
| 426 |
+
"LEditsPPPipelineStableDiffusionXL",
|
| 427 |
+
"LTXConditionPipeline",
|
| 428 |
+
"LTXImageToVideoPipeline",
|
| 429 |
+
"LTXLatentUpsamplePipeline",
|
| 430 |
+
"LTXPipeline",
|
| 431 |
+
"Lumina2Pipeline",
|
| 432 |
+
"Lumina2Text2ImgPipeline",
|
| 433 |
+
"LuminaPipeline",
|
| 434 |
+
"LuminaText2ImgPipeline",
|
| 435 |
+
"MarigoldDepthPipeline",
|
| 436 |
+
"MarigoldIntrinsicsPipeline",
|
| 437 |
+
"MarigoldNormalsPipeline",
|
| 438 |
+
"MochiPipeline",
|
| 439 |
+
"MusicLDMPipeline",
|
| 440 |
+
"OmniGenPipeline",
|
| 441 |
+
"PaintByExamplePipeline",
|
| 442 |
+
"PIAPipeline",
|
| 443 |
+
"PixArtAlphaPipeline",
|
| 444 |
+
"PixArtSigmaPAGPipeline",
|
| 445 |
+
"PixArtSigmaPipeline",
|
| 446 |
+
"ReduxImageEncoder",
|
| 447 |
+
"SanaControlNetPipeline",
|
| 448 |
+
"SanaPAGPipeline",
|
| 449 |
+
"SanaPipeline",
|
| 450 |
+
"SanaSprintImg2ImgPipeline",
|
| 451 |
+
"SanaSprintPipeline",
|
| 452 |
+
"SemanticStableDiffusionPipeline",
|
| 453 |
+
"ShapEImg2ImgPipeline",
|
| 454 |
+
"ShapEPipeline",
|
| 455 |
+
"StableAudioPipeline",
|
| 456 |
+
"StableAudioProjectionModel",
|
| 457 |
+
"StableCascadeCombinedPipeline",
|
| 458 |
+
"StableCascadeDecoderPipeline",
|
| 459 |
+
"StableCascadePriorPipeline",
|
| 460 |
+
"StableDiffusion3ControlNetInpaintingPipeline",
|
| 461 |
+
"StableDiffusion3ControlNetPipeline",
|
| 462 |
+
"StableDiffusion3Img2ImgPipeline",
|
| 463 |
+
"StableDiffusion3InpaintPipeline",
|
| 464 |
+
"StableDiffusion3PAGImg2ImgPipeline",
|
| 465 |
+
"StableDiffusion3PAGImg2ImgPipeline",
|
| 466 |
+
"StableDiffusion3PAGPipeline",
|
| 467 |
+
"StableDiffusion3Pipeline",
|
| 468 |
+
"StableDiffusionAdapterPipeline",
|
| 469 |
+
"StableDiffusionAttendAndExcitePipeline",
|
| 470 |
+
"StableDiffusionControlNetImg2ImgPipeline",
|
| 471 |
+
"StableDiffusionControlNetInpaintPipeline",
|
| 472 |
+
"StableDiffusionControlNetPAGInpaintPipeline",
|
| 473 |
+
"StableDiffusionControlNetPAGPipeline",
|
| 474 |
+
"StableDiffusionControlNetPipeline",
|
| 475 |
+
"StableDiffusionControlNetXSPipeline",
|
| 476 |
+
"StableDiffusionDepth2ImgPipeline",
|
| 477 |
+
"StableDiffusionDiffEditPipeline",
|
| 478 |
+
"StableDiffusionGLIGENPipeline",
|
| 479 |
+
"StableDiffusionGLIGENTextImagePipeline",
|
| 480 |
+
"StableDiffusionImageVariationPipeline",
|
| 481 |
+
"StableDiffusionImg2ImgPipeline",
|
| 482 |
+
"StableDiffusionInpaintPipeline",
|
| 483 |
+
"StableDiffusionInpaintPipelineLegacy",
|
| 484 |
+
"StableDiffusionInstructPix2PixPipeline",
|
| 485 |
+
"StableDiffusionLatentUpscalePipeline",
|
| 486 |
+
"StableDiffusionLDM3DPipeline",
|
| 487 |
+
"StableDiffusionModelEditingPipeline",
|
| 488 |
+
"StableDiffusionPAGImg2ImgPipeline",
|
| 489 |
+
"StableDiffusionPAGInpaintPipeline",
|
| 490 |
+
"StableDiffusionPAGPipeline",
|
| 491 |
+
"StableDiffusionPanoramaPipeline",
|
| 492 |
+
"StableDiffusionParadigmsPipeline",
|
| 493 |
+
"StableDiffusionPipeline",
|
| 494 |
+
"StableDiffusionPipelineSafe",
|
| 495 |
+
"StableDiffusionPix2PixZeroPipeline",
|
| 496 |
+
"StableDiffusionSAGPipeline",
|
| 497 |
+
"StableDiffusionUpscalePipeline",
|
| 498 |
+
"StableDiffusionXLAdapterPipeline",
|
| 499 |
+
"StableDiffusionXLControlNetImg2ImgPipeline",
|
| 500 |
+
"StableDiffusionXLControlNetInpaintPipeline",
|
| 501 |
+
"StableDiffusionXLControlNetPAGImg2ImgPipeline",
|
| 502 |
+
"StableDiffusionXLControlNetPAGPipeline",
|
| 503 |
+
"StableDiffusionXLControlNetPipeline",
|
| 504 |
+
"StableDiffusionXLControlNetUnionImg2ImgPipeline",
|
| 505 |
+
"StableDiffusionXLControlNetUnionInpaintPipeline",
|
| 506 |
+
"StableDiffusionXLControlNetUnionPipeline",
|
| 507 |
+
"StableDiffusionXLControlNetXSPipeline",
|
| 508 |
+
"StableDiffusionXLImg2ImgPipeline",
|
| 509 |
+
"StableDiffusionXLInpaintPipeline",
|
| 510 |
+
"StableDiffusionXLInstructPix2PixPipeline",
|
| 511 |
+
"StableDiffusionXLPAGImg2ImgPipeline",
|
| 512 |
+
"StableDiffusionXLPAGInpaintPipeline",
|
| 513 |
+
"StableDiffusionXLPAGPipeline",
|
| 514 |
+
"StableDiffusionXLPipeline",
|
| 515 |
+
"StableUnCLIPImg2ImgPipeline",
|
| 516 |
+
"StableUnCLIPPipeline",
|
| 517 |
+
"StableVideoDiffusionPipeline",
|
| 518 |
+
"TextToVideoSDPipeline",
|
| 519 |
+
"TextToVideoZeroPipeline",
|
| 520 |
+
"TextToVideoZeroSDXLPipeline",
|
| 521 |
+
"UnCLIPImageVariationPipeline",
|
| 522 |
+
"UnCLIPPipeline",
|
| 523 |
+
"UniDiffuserModel",
|
| 524 |
+
"UniDiffuserPipeline",
|
| 525 |
+
"UniDiffuserTextDecoder",
|
| 526 |
+
"VersatileDiffusionDualGuidedPipeline",
|
| 527 |
+
"VersatileDiffusionImageVariationPipeline",
|
| 528 |
+
"VersatileDiffusionPipeline",
|
| 529 |
+
"VersatileDiffusionTextToImagePipeline",
|
| 530 |
+
"VideoToVideoSDPipeline",
|
| 531 |
+
"VisualClozeGenerationPipeline",
|
| 532 |
+
"VisualClozePipeline",
|
| 533 |
+
"VQDiffusionPipeline",
|
| 534 |
+
"WanImageToVideoPipeline",
|
| 535 |
+
"WanPipeline",
|
| 536 |
+
"WanVACEPipeline",
|
| 537 |
+
"WanVideoToVideoPipeline",
|
| 538 |
+
"WuerstchenCombinedPipeline",
|
| 539 |
+
"WuerstchenDecoderPipeline",
|
| 540 |
+
"WuerstchenPriorPipeline",
|
| 541 |
+
]
|
| 542 |
+
)
|
| 543 |
+
|
| 544 |
+
try:
|
| 545 |
+
if not (is_torch_available() and is_transformers_available() and is_opencv_available()):
|
| 546 |
+
raise OptionalDependencyNotAvailable()
|
| 547 |
+
except OptionalDependencyNotAvailable:
|
| 548 |
+
from .utils import dummy_torch_and_transformers_and_opencv_objects # noqa F403
|
| 549 |
+
|
| 550 |
+
_import_structure["utils.dummy_torch_and_transformers_and_opencv_objects"] = [
|
| 551 |
+
name for name in dir(dummy_torch_and_transformers_and_opencv_objects) if not name.startswith("_")
|
| 552 |
+
]
|
| 553 |
+
|
| 554 |
+
else:
|
| 555 |
+
_import_structure["pipelines"].extend(["ConsisIDPipeline"])
|
| 556 |
+
|
| 557 |
+
try:
|
| 558 |
+
if not (is_torch_available() and is_transformers_available() and is_k_diffusion_available()):
|
| 559 |
+
raise OptionalDependencyNotAvailable()
|
| 560 |
+
except OptionalDependencyNotAvailable:
|
| 561 |
+
from .utils import dummy_torch_and_transformers_and_k_diffusion_objects # noqa F403
|
| 562 |
+
|
| 563 |
+
_import_structure["utils.dummy_torch_and_transformers_and_k_diffusion_objects"] = [
|
| 564 |
+
name for name in dir(dummy_torch_and_transformers_and_k_diffusion_objects) if not name.startswith("_")
|
| 565 |
+
]
|
| 566 |
+
|
| 567 |
+
else:
|
| 568 |
+
_import_structure["pipelines"].extend(["StableDiffusionKDiffusionPipeline", "StableDiffusionXLKDiffusionPipeline"])
|
| 569 |
+
|
| 570 |
+
try:
|
| 571 |
+
if not (is_torch_available() and is_transformers_available() and is_sentencepiece_available()):
|
| 572 |
+
raise OptionalDependencyNotAvailable()
|
| 573 |
+
except OptionalDependencyNotAvailable:
|
| 574 |
+
from .utils import dummy_torch_and_transformers_and_sentencepiece_objects # noqa F403
|
| 575 |
+
|
| 576 |
+
_import_structure["utils.dummy_torch_and_transformers_and_sentencepiece_objects"] = [
|
| 577 |
+
name for name in dir(dummy_torch_and_transformers_and_sentencepiece_objects) if not name.startswith("_")
|
| 578 |
+
]
|
| 579 |
+
|
| 580 |
+
else:
|
| 581 |
+
_import_structure["pipelines"].extend(["KolorsImg2ImgPipeline", "KolorsPAGPipeline", "KolorsPipeline"])
|
| 582 |
+
|
| 583 |
+
try:
|
| 584 |
+
if not (is_torch_available() and is_transformers_available() and is_onnx_available()):
|
| 585 |
+
raise OptionalDependencyNotAvailable()
|
| 586 |
+
except OptionalDependencyNotAvailable:
|
| 587 |
+
from .utils import dummy_torch_and_transformers_and_onnx_objects # noqa F403
|
| 588 |
+
|
| 589 |
+
_import_structure["utils.dummy_torch_and_transformers_and_onnx_objects"] = [
|
| 590 |
+
name for name in dir(dummy_torch_and_transformers_and_onnx_objects) if not name.startswith("_")
|
| 591 |
+
]
|
| 592 |
+
|
| 593 |
+
else:
|
| 594 |
+
_import_structure["pipelines"].extend(
|
| 595 |
+
[
|
| 596 |
+
"OnnxStableDiffusionImg2ImgPipeline",
|
| 597 |
+
"OnnxStableDiffusionInpaintPipeline",
|
| 598 |
+
"OnnxStableDiffusionInpaintPipelineLegacy",
|
| 599 |
+
"OnnxStableDiffusionPipeline",
|
| 600 |
+
"OnnxStableDiffusionUpscalePipeline",
|
| 601 |
+
"StableDiffusionOnnxPipeline",
|
| 602 |
+
]
|
| 603 |
+
)
|
| 604 |
+
|
| 605 |
+
try:
|
| 606 |
+
if not (is_torch_available() and is_librosa_available()):
|
| 607 |
+
raise OptionalDependencyNotAvailable()
|
| 608 |
+
except OptionalDependencyNotAvailable:
|
| 609 |
+
from .utils import dummy_torch_and_librosa_objects # noqa F403
|
| 610 |
+
|
| 611 |
+
_import_structure["utils.dummy_torch_and_librosa_objects"] = [
|
| 612 |
+
name for name in dir(dummy_torch_and_librosa_objects) if not name.startswith("_")
|
| 613 |
+
]
|
| 614 |
+
|
| 615 |
+
else:
|
| 616 |
+
_import_structure["pipelines"].extend(["AudioDiffusionPipeline", "Mel"])
|
| 617 |
+
|
| 618 |
+
try:
|
| 619 |
+
if not (is_transformers_available() and is_torch_available() and is_note_seq_available()):
|
| 620 |
+
raise OptionalDependencyNotAvailable()
|
| 621 |
+
except OptionalDependencyNotAvailable:
|
| 622 |
+
from .utils import dummy_transformers_and_torch_and_note_seq_objects # noqa F403
|
| 623 |
+
|
| 624 |
+
_import_structure["utils.dummy_transformers_and_torch_and_note_seq_objects"] = [
|
| 625 |
+
name for name in dir(dummy_transformers_and_torch_and_note_seq_objects) if not name.startswith("_")
|
| 626 |
+
]
|
| 627 |
+
|
| 628 |
+
|
| 629 |
+
else:
|
| 630 |
+
_import_structure["pipelines"].extend(["SpectrogramDiffusionPipeline"])
|
| 631 |
+
|
| 632 |
+
try:
|
| 633 |
+
if not is_flax_available():
|
| 634 |
+
raise OptionalDependencyNotAvailable()
|
| 635 |
+
except OptionalDependencyNotAvailable:
|
| 636 |
+
from .utils import dummy_flax_objects # noqa F403
|
| 637 |
+
|
| 638 |
+
_import_structure["utils.dummy_flax_objects"] = [
|
| 639 |
+
name for name in dir(dummy_flax_objects) if not name.startswith("_")
|
| 640 |
+
]
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
else:
|
| 644 |
+
_import_structure["models.controlnets.controlnet_flax"] = ["FlaxControlNetModel"]
|
| 645 |
+
_import_structure["models.modeling_flax_utils"] = ["FlaxModelMixin"]
|
| 646 |
+
_import_structure["models.unets.unet_2d_condition_flax"] = ["FlaxUNet2DConditionModel"]
|
| 647 |
+
_import_structure["models.vae_flax"] = ["FlaxAutoencoderKL"]
|
| 648 |
+
_import_structure["pipelines"].extend(["FlaxDiffusionPipeline"])
|
| 649 |
+
_import_structure["schedulers"].extend(
|
| 650 |
+
[
|
| 651 |
+
"FlaxDDIMScheduler",
|
| 652 |
+
"FlaxDDPMScheduler",
|
| 653 |
+
"FlaxDPMSolverMultistepScheduler",
|
| 654 |
+
"FlaxEulerDiscreteScheduler",
|
| 655 |
+
"FlaxKarrasVeScheduler",
|
| 656 |
+
"FlaxLMSDiscreteScheduler",
|
| 657 |
+
"FlaxPNDMScheduler",
|
| 658 |
+
"FlaxSchedulerMixin",
|
| 659 |
+
"FlaxScoreSdeVeScheduler",
|
| 660 |
+
]
|
| 661 |
+
)
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
try:
|
| 665 |
+
if not (is_flax_available() and is_transformers_available()):
|
| 666 |
+
raise OptionalDependencyNotAvailable()
|
| 667 |
+
except OptionalDependencyNotAvailable:
|
| 668 |
+
from .utils import dummy_flax_and_transformers_objects # noqa F403
|
| 669 |
+
|
| 670 |
+
_import_structure["utils.dummy_flax_and_transformers_objects"] = [
|
| 671 |
+
name for name in dir(dummy_flax_and_transformers_objects) if not name.startswith("_")
|
| 672 |
+
]
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
else:
|
| 676 |
+
_import_structure["pipelines"].extend(
|
| 677 |
+
[
|
| 678 |
+
"FlaxStableDiffusionControlNetPipeline",
|
| 679 |
+
"FlaxStableDiffusionImg2ImgPipeline",
|
| 680 |
+
"FlaxStableDiffusionInpaintPipeline",
|
| 681 |
+
"FlaxStableDiffusionPipeline",
|
| 682 |
+
"FlaxStableDiffusionXLPipeline",
|
| 683 |
+
]
|
| 684 |
+
)
|
| 685 |
+
|
| 686 |
+
try:
|
| 687 |
+
if not (is_note_seq_available()):
|
| 688 |
+
raise OptionalDependencyNotAvailable()
|
| 689 |
+
except OptionalDependencyNotAvailable:
|
| 690 |
+
from .utils import dummy_note_seq_objects # noqa F403
|
| 691 |
+
|
| 692 |
+
_import_structure["utils.dummy_note_seq_objects"] = [
|
| 693 |
+
name for name in dir(dummy_note_seq_objects) if not name.startswith("_")
|
| 694 |
+
]
|
| 695 |
+
|
| 696 |
+
|
| 697 |
+
else:
|
| 698 |
+
_import_structure["pipelines"].extend(["MidiProcessor"])
|
| 699 |
+
|
| 700 |
+
if TYPE_CHECKING or DIFFUSERS_SLOW_IMPORT:
|
| 701 |
+
from .configuration_utils import ConfigMixin
|
| 702 |
+
from .quantizers import PipelineQuantizationConfig
|
| 703 |
+
|
| 704 |
+
try:
|
| 705 |
+
if not is_bitsandbytes_available():
|
| 706 |
+
raise OptionalDependencyNotAvailable()
|
| 707 |
+
except OptionalDependencyNotAvailable:
|
| 708 |
+
from .utils.dummy_bitsandbytes_objects import *
|
| 709 |
+
else:
|
| 710 |
+
from .quantizers.quantization_config import BitsAndBytesConfig
|
| 711 |
+
|
| 712 |
+
try:
|
| 713 |
+
if not is_gguf_available():
|
| 714 |
+
raise OptionalDependencyNotAvailable()
|
| 715 |
+
except OptionalDependencyNotAvailable:
|
| 716 |
+
from .utils.dummy_gguf_objects import *
|
| 717 |
+
else:
|
| 718 |
+
from .quantizers.quantization_config import GGUFQuantizationConfig
|
| 719 |
+
|
| 720 |
+
try:
|
| 721 |
+
if not is_torchao_available():
|
| 722 |
+
raise OptionalDependencyNotAvailable()
|
| 723 |
+
except OptionalDependencyNotAvailable:
|
| 724 |
+
from .utils.dummy_torchao_objects import *
|
| 725 |
+
else:
|
| 726 |
+
from .quantizers.quantization_config import TorchAoConfig
|
| 727 |
+
|
| 728 |
+
try:
|
| 729 |
+
if not is_optimum_quanto_available():
|
| 730 |
+
raise OptionalDependencyNotAvailable()
|
| 731 |
+
except OptionalDependencyNotAvailable:
|
| 732 |
+
from .utils.dummy_optimum_quanto_objects import *
|
| 733 |
+
else:
|
| 734 |
+
from .quantizers.quantization_config import QuantoConfig
|
| 735 |
+
|
| 736 |
+
try:
|
| 737 |
+
if not is_onnx_available():
|
| 738 |
+
raise OptionalDependencyNotAvailable()
|
| 739 |
+
except OptionalDependencyNotAvailable:
|
| 740 |
+
from .utils.dummy_onnx_objects import * # noqa F403
|
| 741 |
+
else:
|
| 742 |
+
from .pipelines import OnnxRuntimeModel
|
| 743 |
+
|
| 744 |
+
try:
|
| 745 |
+
if not is_torch_available():
|
| 746 |
+
raise OptionalDependencyNotAvailable()
|
| 747 |
+
except OptionalDependencyNotAvailable:
|
| 748 |
+
from .utils.dummy_pt_objects import * # noqa F403
|
| 749 |
+
else:
|
| 750 |
+
from .hooks import (
|
| 751 |
+
FasterCacheConfig,
|
| 752 |
+
HookRegistry,
|
| 753 |
+
PyramidAttentionBroadcastConfig,
|
| 754 |
+
apply_faster_cache,
|
| 755 |
+
apply_pyramid_attention_broadcast,
|
| 756 |
+
)
|
| 757 |
+
from .models import (
|
| 758 |
+
AllegroTransformer3DModel,
|
| 759 |
+
AsymmetricAutoencoderKL,
|
| 760 |
+
AuraFlowTransformer2DModel,
|
| 761 |
+
AutoencoderDC,
|
| 762 |
+
AutoencoderKL,
|
| 763 |
+
AutoencoderKLAllegro,
|
| 764 |
+
AutoencoderKLCogVideoX,
|
| 765 |
+
AutoencoderKLCosmos,
|
| 766 |
+
AutoencoderKLHunyuanVideo,
|
| 767 |
+
AutoencoderKLLTXVideo,
|
| 768 |
+
AutoencoderKLMagvit,
|
| 769 |
+
AutoencoderKLMochi,
|
| 770 |
+
AutoencoderKLTemporalDecoder,
|
| 771 |
+
AutoencoderKLWan,
|
| 772 |
+
AutoencoderOobleck,
|
| 773 |
+
AutoencoderTiny,
|
| 774 |
+
AutoModel,
|
| 775 |
+
CacheMixin,
|
| 776 |
+
ChromaTransformer2DModel,
|
| 777 |
+
CogVideoXTransformer3DModel,
|
| 778 |
+
CogView3PlusTransformer2DModel,
|
| 779 |
+
CogView4Transformer2DModel,
|
| 780 |
+
ConsisIDTransformer3DModel,
|
| 781 |
+
ConsistencyDecoderVAE,
|
| 782 |
+
ControlNetModel,
|
| 783 |
+
ControlNetUnionModel,
|
| 784 |
+
ControlNetXSAdapter,
|
| 785 |
+
CosmosTransformer3DModel,
|
| 786 |
+
DiTTransformer2DModel,
|
| 787 |
+
EasyAnimateTransformer3DModel,
|
| 788 |
+
FluxControlNetModel,
|
| 789 |
+
FluxMultiControlNetModel,
|
| 790 |
+
FluxTransformer2DModel,
|
| 791 |
+
HiDreamImageTransformer2DModel,
|
| 792 |
+
HunyuanDiT2DControlNetModel,
|
| 793 |
+
HunyuanDiT2DModel,
|
| 794 |
+
HunyuanDiT2DMultiControlNetModel,
|
| 795 |
+
HunyuanVideoFramepackTransformer3DModel,
|
| 796 |
+
HunyuanVideoTransformer3DModel,
|
| 797 |
+
I2VGenXLUNet,
|
| 798 |
+
Kandinsky3UNet,
|
| 799 |
+
LatteTransformer3DModel,
|
| 800 |
+
LTXVideoTransformer3DModel,
|
| 801 |
+
Lumina2Transformer2DModel,
|
| 802 |
+
LuminaNextDiT2DModel,
|
| 803 |
+
MochiTransformer3DModel,
|
| 804 |
+
ModelMixin,
|
| 805 |
+
MotionAdapter,
|
| 806 |
+
MultiAdapter,
|
| 807 |
+
MultiControlNetModel,
|
| 808 |
+
OmniGenTransformer2DModel,
|
| 809 |
+
PixArtTransformer2DModel,
|
| 810 |
+
PriorTransformer,
|
| 811 |
+
SanaControlNetModel,
|
| 812 |
+
SanaTransformer2DModel,
|
| 813 |
+
SD3ControlNetModel,
|
| 814 |
+
SD3MultiControlNetModel,
|
| 815 |
+
SD3Transformer2DModel,
|
| 816 |
+
SparseControlNetModel,
|
| 817 |
+
StableAudioDiTModel,
|
| 818 |
+
T2IAdapter,
|
| 819 |
+
T5FilmDecoder,
|
| 820 |
+
Transformer2DModel,
|
| 821 |
+
TransformerTemporalModel,
|
| 822 |
+
UNet1DModel,
|
| 823 |
+
UNet2DConditionModel,
|
| 824 |
+
UNet2DModel,
|
| 825 |
+
UNet3DConditionModel,
|
| 826 |
+
UNetControlNetXSModel,
|
| 827 |
+
UNetMotionModel,
|
| 828 |
+
UNetSpatioTemporalConditionModel,
|
| 829 |
+
UVit2DModel,
|
| 830 |
+
VQModel,
|
| 831 |
+
WanTransformer3DModel,
|
| 832 |
+
WanVACETransformer3DModel,
|
| 833 |
+
)
|
| 834 |
+
from .optimization import (
|
| 835 |
+
get_constant_schedule,
|
| 836 |
+
get_constant_schedule_with_warmup,
|
| 837 |
+
get_cosine_schedule_with_warmup,
|
| 838 |
+
get_cosine_with_hard_restarts_schedule_with_warmup,
|
| 839 |
+
get_linear_schedule_with_warmup,
|
| 840 |
+
get_polynomial_decay_schedule_with_warmup,
|
| 841 |
+
get_scheduler,
|
| 842 |
+
)
|
| 843 |
+
from .pipelines import (
|
| 844 |
+
AudioPipelineOutput,
|
| 845 |
+
AutoPipelineForImage2Image,
|
| 846 |
+
AutoPipelineForInpainting,
|
| 847 |
+
AutoPipelineForText2Image,
|
| 848 |
+
BlipDiffusionControlNetPipeline,
|
| 849 |
+
BlipDiffusionPipeline,
|
| 850 |
+
CLIPImageProjection,
|
| 851 |
+
ConsistencyModelPipeline,
|
| 852 |
+
DanceDiffusionPipeline,
|
| 853 |
+
DDIMPipeline,
|
| 854 |
+
DDPMPipeline,
|
| 855 |
+
DiffusionPipeline,
|
| 856 |
+
DiTPipeline,
|
| 857 |
+
ImagePipelineOutput,
|
| 858 |
+
KarrasVePipeline,
|
| 859 |
+
LDMPipeline,
|
| 860 |
+
LDMSuperResolutionPipeline,
|
| 861 |
+
PNDMPipeline,
|
| 862 |
+
RePaintPipeline,
|
| 863 |
+
ScoreSdeVePipeline,
|
| 864 |
+
StableDiffusionMixin,
|
| 865 |
+
)
|
| 866 |
+
from .quantizers import DiffusersQuantizer
|
| 867 |
+
from .schedulers import (
|
| 868 |
+
AmusedScheduler,
|
| 869 |
+
CMStochasticIterativeScheduler,
|
| 870 |
+
CogVideoXDDIMScheduler,
|
| 871 |
+
CogVideoXDPMScheduler,
|
| 872 |
+
DDIMInverseScheduler,
|
| 873 |
+
DDIMParallelScheduler,
|
| 874 |
+
DDIMScheduler,
|
| 875 |
+
DDPMParallelScheduler,
|
| 876 |
+
DDPMScheduler,
|
| 877 |
+
DDPMWuerstchenScheduler,
|
| 878 |
+
DEISMultistepScheduler,
|
| 879 |
+
DPMSolverMultistepInverseScheduler,
|
| 880 |
+
DPMSolverMultistepScheduler,
|
| 881 |
+
DPMSolverSinglestepScheduler,
|
| 882 |
+
EDMDPMSolverMultistepScheduler,
|
| 883 |
+
EDMEulerScheduler,
|
| 884 |
+
EulerAncestralDiscreteScheduler,
|
| 885 |
+
EulerDiscreteScheduler,
|
| 886 |
+
FlowMatchEulerDiscreteScheduler,
|
| 887 |
+
FlowMatchHeunDiscreteScheduler,
|
| 888 |
+
FlowMatchLCMScheduler,
|
| 889 |
+
HeunDiscreteScheduler,
|
| 890 |
+
IPNDMScheduler,
|
| 891 |
+
KarrasVeScheduler,
|
| 892 |
+
KDPM2AncestralDiscreteScheduler,
|
| 893 |
+
KDPM2DiscreteScheduler,
|
| 894 |
+
LCMScheduler,
|
| 895 |
+
PNDMScheduler,
|
| 896 |
+
RePaintScheduler,
|
| 897 |
+
SASolverScheduler,
|
| 898 |
+
SchedulerMixin,
|
| 899 |
+
SCMScheduler,
|
| 900 |
+
ScoreSdeVeScheduler,
|
| 901 |
+
TCDScheduler,
|
| 902 |
+
UnCLIPScheduler,
|
| 903 |
+
UniPCMultistepScheduler,
|
| 904 |
+
VQDiffusionScheduler,
|
| 905 |
+
)
|
| 906 |
+
from .training_utils import EMAModel
|
| 907 |
+
|
| 908 |
+
try:
|
| 909 |
+
if not (is_torch_available() and is_scipy_available()):
|
| 910 |
+
raise OptionalDependencyNotAvailable()
|
| 911 |
+
except OptionalDependencyNotAvailable:
|
| 912 |
+
from .utils.dummy_torch_and_scipy_objects import * # noqa F403
|
| 913 |
+
else:
|
| 914 |
+
from .schedulers import LMSDiscreteScheduler
|
| 915 |
+
|
| 916 |
+
try:
|
| 917 |
+
if not (is_torch_available() and is_torchsde_available()):
|
| 918 |
+
raise OptionalDependencyNotAvailable()
|
| 919 |
+
except OptionalDependencyNotAvailable:
|
| 920 |
+
from .utils.dummy_torch_and_torchsde_objects import * # noqa F403
|
| 921 |
+
else:
|
| 922 |
+
from .schedulers import CosineDPMSolverMultistepScheduler, DPMSolverSDEScheduler
|
| 923 |
+
|
| 924 |
+
try:
|
| 925 |
+
if not (is_torch_available() and is_transformers_available()):
|
| 926 |
+
raise OptionalDependencyNotAvailable()
|
| 927 |
+
except OptionalDependencyNotAvailable:
|
| 928 |
+
from .utils.dummy_torch_and_transformers_objects import * # noqa F403
|
| 929 |
+
else:
|
| 930 |
+
from .pipelines import (
|
| 931 |
+
AllegroPipeline,
|
| 932 |
+
AltDiffusionImg2ImgPipeline,
|
| 933 |
+
AltDiffusionPipeline,
|
| 934 |
+
AmusedImg2ImgPipeline,
|
| 935 |
+
AmusedInpaintPipeline,
|
| 936 |
+
AmusedPipeline,
|
| 937 |
+
AnimateDiffControlNetPipeline,
|
| 938 |
+
AnimateDiffPAGPipeline,
|
| 939 |
+
AnimateDiffPipeline,
|
| 940 |
+
AnimateDiffSDXLPipeline,
|
| 941 |
+
AnimateDiffSparseControlNetPipeline,
|
| 942 |
+
AnimateDiffVideoToVideoControlNetPipeline,
|
| 943 |
+
AnimateDiffVideoToVideoPipeline,
|
| 944 |
+
AudioLDM2Pipeline,
|
| 945 |
+
AudioLDM2ProjectionModel,
|
| 946 |
+
AudioLDM2UNet2DConditionModel,
|
| 947 |
+
AudioLDMPipeline,
|
| 948 |
+
AuraFlowPipeline,
|
| 949 |
+
ChromaImg2ImgPipeline,
|
| 950 |
+
ChromaPipeline,
|
| 951 |
+
CLIPImageProjection,
|
| 952 |
+
CogVideoXFunControlPipeline,
|
| 953 |
+
CogVideoXImageToVideoPipeline,
|
| 954 |
+
CogVideoXPipeline,
|
| 955 |
+
CogVideoXVideoToVideoPipeline,
|
| 956 |
+
CogView3PlusPipeline,
|
| 957 |
+
CogView4ControlPipeline,
|
| 958 |
+
CogView4Pipeline,
|
| 959 |
+
ConsisIDPipeline,
|
| 960 |
+
Cosmos2TextToImagePipeline,
|
| 961 |
+
Cosmos2VideoToWorldPipeline,
|
| 962 |
+
CosmosTextToWorldPipeline,
|
| 963 |
+
CosmosVideoToWorldPipeline,
|
| 964 |
+
CycleDiffusionPipeline,
|
| 965 |
+
EasyAnimateControlPipeline,
|
| 966 |
+
EasyAnimateInpaintPipeline,
|
| 967 |
+
EasyAnimatePipeline,
|
| 968 |
+
FluxControlImg2ImgPipeline,
|
| 969 |
+
FluxControlInpaintPipeline,
|
| 970 |
+
FluxControlNetImg2ImgPipeline,
|
| 971 |
+
FluxControlNetInpaintPipeline,
|
| 972 |
+
FluxControlNetPipeline,
|
| 973 |
+
FluxControlPipeline,
|
| 974 |
+
FluxFillPipeline,
|
| 975 |
+
FluxImg2ImgPipeline,
|
| 976 |
+
FluxInpaintPipeline,
|
| 977 |
+
FluxPipeline,
|
| 978 |
+
FluxPriorReduxPipeline,
|
| 979 |
+
HiDreamImagePipeline,
|
| 980 |
+
HunyuanDiTControlNetPipeline,
|
| 981 |
+
HunyuanDiTPAGPipeline,
|
| 982 |
+
HunyuanDiTPipeline,
|
| 983 |
+
HunyuanSkyreelsImageToVideoPipeline,
|
| 984 |
+
HunyuanVideoFramepackPipeline,
|
| 985 |
+
HunyuanVideoImageToVideoPipeline,
|
| 986 |
+
HunyuanVideoPipeline,
|
| 987 |
+
I2VGenXLPipeline,
|
| 988 |
+
IFImg2ImgPipeline,
|
| 989 |
+
IFImg2ImgSuperResolutionPipeline,
|
| 990 |
+
IFInpaintingPipeline,
|
| 991 |
+
IFInpaintingSuperResolutionPipeline,
|
| 992 |
+
IFPipeline,
|
| 993 |
+
IFSuperResolutionPipeline,
|
| 994 |
+
ImageTextPipelineOutput,
|
| 995 |
+
Kandinsky3Img2ImgPipeline,
|
| 996 |
+
Kandinsky3Pipeline,
|
| 997 |
+
KandinskyCombinedPipeline,
|
| 998 |
+
KandinskyImg2ImgCombinedPipeline,
|
| 999 |
+
KandinskyImg2ImgPipeline,
|
| 1000 |
+
KandinskyInpaintCombinedPipeline,
|
| 1001 |
+
KandinskyInpaintPipeline,
|
| 1002 |
+
KandinskyPipeline,
|
| 1003 |
+
KandinskyPriorPipeline,
|
| 1004 |
+
KandinskyV22CombinedPipeline,
|
| 1005 |
+
KandinskyV22ControlnetImg2ImgPipeline,
|
| 1006 |
+
KandinskyV22ControlnetPipeline,
|
| 1007 |
+
KandinskyV22Img2ImgCombinedPipeline,
|
| 1008 |
+
KandinskyV22Img2ImgPipeline,
|
| 1009 |
+
KandinskyV22InpaintCombinedPipeline,
|
| 1010 |
+
KandinskyV22InpaintPipeline,
|
| 1011 |
+
KandinskyV22Pipeline,
|
| 1012 |
+
KandinskyV22PriorEmb2EmbPipeline,
|
| 1013 |
+
KandinskyV22PriorPipeline,
|
| 1014 |
+
LatentConsistencyModelImg2ImgPipeline,
|
| 1015 |
+
LatentConsistencyModelPipeline,
|
| 1016 |
+
LattePipeline,
|
| 1017 |
+
LDMTextToImagePipeline,
|
| 1018 |
+
LEditsPPPipelineStableDiffusion,
|
| 1019 |
+
LEditsPPPipelineStableDiffusionXL,
|
| 1020 |
+
LTXConditionPipeline,
|
| 1021 |
+
LTXImageToVideoPipeline,
|
| 1022 |
+
LTXLatentUpsamplePipeline,
|
| 1023 |
+
LTXPipeline,
|
| 1024 |
+
Lumina2Pipeline,
|
| 1025 |
+
Lumina2Text2ImgPipeline,
|
| 1026 |
+
LuminaPipeline,
|
| 1027 |
+
LuminaText2ImgPipeline,
|
| 1028 |
+
MarigoldDepthPipeline,
|
| 1029 |
+
MarigoldIntrinsicsPipeline,
|
| 1030 |
+
MarigoldNormalsPipeline,
|
| 1031 |
+
MochiPipeline,
|
| 1032 |
+
MusicLDMPipeline,
|
| 1033 |
+
OmniGenPipeline,
|
| 1034 |
+
PaintByExamplePipeline,
|
| 1035 |
+
PIAPipeline,
|
| 1036 |
+
PixArtAlphaPipeline,
|
| 1037 |
+
PixArtSigmaPAGPipeline,
|
| 1038 |
+
PixArtSigmaPipeline,
|
| 1039 |
+
ReduxImageEncoder,
|
| 1040 |
+
SanaControlNetPipeline,
|
| 1041 |
+
SanaPAGPipeline,
|
| 1042 |
+
SanaPipeline,
|
| 1043 |
+
SanaSprintImg2ImgPipeline,
|
| 1044 |
+
SanaSprintPipeline,
|
| 1045 |
+
SemanticStableDiffusionPipeline,
|
| 1046 |
+
ShapEImg2ImgPipeline,
|
| 1047 |
+
ShapEPipeline,
|
| 1048 |
+
StableAudioPipeline,
|
| 1049 |
+
StableAudioProjectionModel,
|
| 1050 |
+
StableCascadeCombinedPipeline,
|
| 1051 |
+
StableCascadeDecoderPipeline,
|
| 1052 |
+
StableCascadePriorPipeline,
|
| 1053 |
+
StableDiffusion3ControlNetInpaintingPipeline,
|
| 1054 |
+
StableDiffusion3ControlNetPipeline,
|
| 1055 |
+
StableDiffusion3Img2ImgPipeline,
|
| 1056 |
+
StableDiffusion3InpaintPipeline,
|
| 1057 |
+
StableDiffusion3PAGImg2ImgPipeline,
|
| 1058 |
+
StableDiffusion3PAGPipeline,
|
| 1059 |
+
StableDiffusion3Pipeline,
|
| 1060 |
+
StableDiffusionAdapterPipeline,
|
| 1061 |
+
StableDiffusionAttendAndExcitePipeline,
|
| 1062 |
+
StableDiffusionControlNetImg2ImgPipeline,
|
| 1063 |
+
StableDiffusionControlNetInpaintPipeline,
|
| 1064 |
+
StableDiffusionControlNetPAGInpaintPipeline,
|
| 1065 |
+
StableDiffusionControlNetPAGPipeline,
|
| 1066 |
+
StableDiffusionControlNetPipeline,
|
| 1067 |
+
StableDiffusionControlNetXSPipeline,
|
| 1068 |
+
StableDiffusionDepth2ImgPipeline,
|
| 1069 |
+
StableDiffusionDiffEditPipeline,
|
| 1070 |
+
StableDiffusionGLIGENPipeline,
|
| 1071 |
+
StableDiffusionGLIGENTextImagePipeline,
|
| 1072 |
+
StableDiffusionImageVariationPipeline,
|
| 1073 |
+
StableDiffusionImg2ImgPipeline,
|
| 1074 |
+
StableDiffusionInpaintPipeline,
|
| 1075 |
+
StableDiffusionInpaintPipelineLegacy,
|
| 1076 |
+
StableDiffusionInstructPix2PixPipeline,
|
| 1077 |
+
StableDiffusionLatentUpscalePipeline,
|
| 1078 |
+
StableDiffusionLDM3DPipeline,
|
| 1079 |
+
StableDiffusionModelEditingPipeline,
|
| 1080 |
+
StableDiffusionPAGImg2ImgPipeline,
|
| 1081 |
+
StableDiffusionPAGInpaintPipeline,
|
| 1082 |
+
StableDiffusionPAGPipeline,
|
| 1083 |
+
StableDiffusionPanoramaPipeline,
|
| 1084 |
+
StableDiffusionParadigmsPipeline,
|
| 1085 |
+
StableDiffusionPipeline,
|
| 1086 |
+
StableDiffusionPipelineSafe,
|
| 1087 |
+
StableDiffusionPix2PixZeroPipeline,
|
| 1088 |
+
StableDiffusionSAGPipeline,
|
| 1089 |
+
StableDiffusionUpscalePipeline,
|
| 1090 |
+
StableDiffusionXLAdapterPipeline,
|
| 1091 |
+
StableDiffusionXLControlNetImg2ImgPipeline,
|
| 1092 |
+
StableDiffusionXLControlNetInpaintPipeline,
|
| 1093 |
+
StableDiffusionXLControlNetPAGImg2ImgPipeline,
|
| 1094 |
+
StableDiffusionXLControlNetPAGPipeline,
|
| 1095 |
+
StableDiffusionXLControlNetPipeline,
|
| 1096 |
+
StableDiffusionXLControlNetUnionImg2ImgPipeline,
|
| 1097 |
+
StableDiffusionXLControlNetUnionInpaintPipeline,
|
| 1098 |
+
StableDiffusionXLControlNetUnionPipeline,
|
| 1099 |
+
StableDiffusionXLControlNetXSPipeline,
|
| 1100 |
+
StableDiffusionXLImg2ImgPipeline,
|
| 1101 |
+
StableDiffusionXLInpaintPipeline,
|
| 1102 |
+
StableDiffusionXLInstructPix2PixPipeline,
|
| 1103 |
+
StableDiffusionXLPAGImg2ImgPipeline,
|
| 1104 |
+
StableDiffusionXLPAGInpaintPipeline,
|
| 1105 |
+
StableDiffusionXLPAGPipeline,
|
| 1106 |
+
StableDiffusionXLPipeline,
|
| 1107 |
+
StableUnCLIPImg2ImgPipeline,
|
| 1108 |
+
StableUnCLIPPipeline,
|
| 1109 |
+
StableVideoDiffusionPipeline,
|
| 1110 |
+
TextToVideoSDPipeline,
|
| 1111 |
+
TextToVideoZeroPipeline,
|
| 1112 |
+
TextToVideoZeroSDXLPipeline,
|
| 1113 |
+
UnCLIPImageVariationPipeline,
|
| 1114 |
+
UnCLIPPipeline,
|
| 1115 |
+
UniDiffuserModel,
|
| 1116 |
+
UniDiffuserPipeline,
|
| 1117 |
+
UniDiffuserTextDecoder,
|
| 1118 |
+
VersatileDiffusionDualGuidedPipeline,
|
| 1119 |
+
VersatileDiffusionImageVariationPipeline,
|
| 1120 |
+
VersatileDiffusionPipeline,
|
| 1121 |
+
VersatileDiffusionTextToImagePipeline,
|
| 1122 |
+
VideoToVideoSDPipeline,
|
| 1123 |
+
VisualClozeGenerationPipeline,
|
| 1124 |
+
VisualClozePipeline,
|
| 1125 |
+
VQDiffusionPipeline,
|
| 1126 |
+
WanImageToVideoPipeline,
|
| 1127 |
+
WanPipeline,
|
| 1128 |
+
WanVACEPipeline,
|
| 1129 |
+
WanVideoToVideoPipeline,
|
| 1130 |
+
WuerstchenCombinedPipeline,
|
| 1131 |
+
WuerstchenDecoderPipeline,
|
| 1132 |
+
WuerstchenPriorPipeline,
|
| 1133 |
+
)
|
| 1134 |
+
|
| 1135 |
+
try:
|
| 1136 |
+
if not (is_torch_available() and is_transformers_available() and is_k_diffusion_available()):
|
| 1137 |
+
raise OptionalDependencyNotAvailable()
|
| 1138 |
+
except OptionalDependencyNotAvailable:
|
| 1139 |
+
from .utils.dummy_torch_and_transformers_and_k_diffusion_objects import * # noqa F403
|
| 1140 |
+
else:
|
| 1141 |
+
from .pipelines import StableDiffusionKDiffusionPipeline, StableDiffusionXLKDiffusionPipeline
|
| 1142 |
+
|
| 1143 |
+
try:
|
| 1144 |
+
if not (is_torch_available() and is_transformers_available() and is_sentencepiece_available()):
|
| 1145 |
+
raise OptionalDependencyNotAvailable()
|
| 1146 |
+
except OptionalDependencyNotAvailable:
|
| 1147 |
+
from .utils.dummy_torch_and_transformers_and_sentencepiece_objects import * # noqa F403
|
| 1148 |
+
else:
|
| 1149 |
+
from .pipelines import KolorsImg2ImgPipeline, KolorsPAGPipeline, KolorsPipeline
|
| 1150 |
+
|
| 1151 |
+
try:
|
| 1152 |
+
if not (is_torch_available() and is_transformers_available() and is_opencv_available()):
|
| 1153 |
+
raise OptionalDependencyNotAvailable()
|
| 1154 |
+
except OptionalDependencyNotAvailable:
|
| 1155 |
+
from .utils.dummy_torch_and_transformers_and_opencv_objects import * # noqa F403
|
| 1156 |
+
else:
|
| 1157 |
+
from .pipelines import ConsisIDPipeline
|
| 1158 |
+
|
| 1159 |
+
try:
|
| 1160 |
+
if not (is_torch_available() and is_transformers_available() and is_onnx_available()):
|
| 1161 |
+
raise OptionalDependencyNotAvailable()
|
| 1162 |
+
except OptionalDependencyNotAvailable:
|
| 1163 |
+
from .utils.dummy_torch_and_transformers_and_onnx_objects import * # noqa F403
|
| 1164 |
+
else:
|
| 1165 |
+
from .pipelines import (
|
| 1166 |
+
OnnxStableDiffusionImg2ImgPipeline,
|
| 1167 |
+
OnnxStableDiffusionInpaintPipeline,
|
| 1168 |
+
OnnxStableDiffusionInpaintPipelineLegacy,
|
| 1169 |
+
OnnxStableDiffusionPipeline,
|
| 1170 |
+
OnnxStableDiffusionUpscalePipeline,
|
| 1171 |
+
StableDiffusionOnnxPipeline,
|
| 1172 |
+
)
|
| 1173 |
+
|
| 1174 |
+
try:
|
| 1175 |
+
if not (is_torch_available() and is_librosa_available()):
|
| 1176 |
+
raise OptionalDependencyNotAvailable()
|
| 1177 |
+
except OptionalDependencyNotAvailable:
|
| 1178 |
+
from .utils.dummy_torch_and_librosa_objects import * # noqa F403
|
| 1179 |
+
else:
|
| 1180 |
+
from .pipelines import AudioDiffusionPipeline, Mel
|
| 1181 |
+
|
| 1182 |
+
try:
|
| 1183 |
+
if not (is_transformers_available() and is_torch_available() and is_note_seq_available()):
|
| 1184 |
+
raise OptionalDependencyNotAvailable()
|
| 1185 |
+
except OptionalDependencyNotAvailable:
|
| 1186 |
+
from .utils.dummy_transformers_and_torch_and_note_seq_objects import * # noqa F403
|
| 1187 |
+
else:
|
| 1188 |
+
from .pipelines import SpectrogramDiffusionPipeline
|
| 1189 |
+
|
| 1190 |
+
try:
|
| 1191 |
+
if not is_flax_available():
|
| 1192 |
+
raise OptionalDependencyNotAvailable()
|
| 1193 |
+
except OptionalDependencyNotAvailable:
|
| 1194 |
+
from .utils.dummy_flax_objects import * # noqa F403
|
| 1195 |
+
else:
|
| 1196 |
+
from .models.controlnets.controlnet_flax import FlaxControlNetModel
|
| 1197 |
+
from .models.modeling_flax_utils import FlaxModelMixin
|
| 1198 |
+
from .models.unets.unet_2d_condition_flax import FlaxUNet2DConditionModel
|
| 1199 |
+
from .models.vae_flax import FlaxAutoencoderKL
|
| 1200 |
+
from .pipelines import FlaxDiffusionPipeline
|
| 1201 |
+
from .schedulers import (
|
| 1202 |
+
FlaxDDIMScheduler,
|
| 1203 |
+
FlaxDDPMScheduler,
|
| 1204 |
+
FlaxDPMSolverMultistepScheduler,
|
| 1205 |
+
FlaxEulerDiscreteScheduler,
|
| 1206 |
+
FlaxKarrasVeScheduler,
|
| 1207 |
+
FlaxLMSDiscreteScheduler,
|
| 1208 |
+
FlaxPNDMScheduler,
|
| 1209 |
+
FlaxSchedulerMixin,
|
| 1210 |
+
FlaxScoreSdeVeScheduler,
|
| 1211 |
+
)
|
| 1212 |
+
|
| 1213 |
+
try:
|
| 1214 |
+
if not (is_flax_available() and is_transformers_available()):
|
| 1215 |
+
raise OptionalDependencyNotAvailable()
|
| 1216 |
+
except OptionalDependencyNotAvailable:
|
| 1217 |
+
from .utils.dummy_flax_and_transformers_objects import * # noqa F403
|
| 1218 |
+
else:
|
| 1219 |
+
from .pipelines import (
|
| 1220 |
+
FlaxStableDiffusionControlNetPipeline,
|
| 1221 |
+
FlaxStableDiffusionImg2ImgPipeline,
|
| 1222 |
+
FlaxStableDiffusionInpaintPipeline,
|
| 1223 |
+
FlaxStableDiffusionPipeline,
|
| 1224 |
+
FlaxStableDiffusionXLPipeline,
|
| 1225 |
+
)
|
| 1226 |
+
|
| 1227 |
+
try:
|
| 1228 |
+
if not (is_note_seq_available()):
|
| 1229 |
+
raise OptionalDependencyNotAvailable()
|
| 1230 |
+
except OptionalDependencyNotAvailable:
|
| 1231 |
+
from .utils.dummy_note_seq_objects import * # noqa F403
|
| 1232 |
+
else:
|
| 1233 |
+
from .pipelines import MidiProcessor
|
| 1234 |
+
|
| 1235 |
+
else:
|
| 1236 |
+
import sys
|
| 1237 |
+
|
| 1238 |
+
sys.modules[__name__] = _LazyModule(
|
| 1239 |
+
__name__,
|
| 1240 |
+
globals()["__file__"],
|
| 1241 |
+
_import_structure,
|
| 1242 |
+
module_spec=__spec__,
|
| 1243 |
+
extra_objects={"__version__": __version__},
|
| 1244 |
+
)
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (25.5 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/callbacks.cpython-310.pyc
ADDED
|
Binary file (7.17 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/configuration_utils.cpython-310.pyc
ADDED
|
Binary file (25.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/dependency_versions_check.cpython-310.pyc
ADDED
|
Binary file (690 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/dependency_versions_table.cpython-310.pyc
ADDED
|
Binary file (1.65 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/image_processor.cpython-310.pyc
ADDED
|
Binary file (42.1 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/optimization.cpython-310.pyc
ADDED
|
Binary file (12.9 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/training_utils.cpython-310.pyc
ADDED
|
Binary file (22.1 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/__pycache__/video_processor.cpython-310.pyc
ADDED
|
Binary file (4.44 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/callbacks.py
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, Dict, List
|
| 2 |
+
|
| 3 |
+
from .configuration_utils import ConfigMixin, register_to_config
|
| 4 |
+
from .utils import CONFIG_NAME
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class PipelineCallback(ConfigMixin):
|
| 8 |
+
"""
|
| 9 |
+
Base class for all the official callbacks used in a pipeline. This class provides a structure for implementing
|
| 10 |
+
custom callbacks and ensures that all callbacks have a consistent interface.
|
| 11 |
+
|
| 12 |
+
Please implement the following:
|
| 13 |
+
`tensor_inputs`: This should return a list of tensor inputs specific to your callback. You will only be able to
|
| 14 |
+
include
|
| 15 |
+
variables listed in the `._callback_tensor_inputs` attribute of your pipeline class.
|
| 16 |
+
`callback_fn`: This method defines the core functionality of your callback.
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
config_name = CONFIG_NAME
|
| 20 |
+
|
| 21 |
+
@register_to_config
|
| 22 |
+
def __init__(self, cutoff_step_ratio=1.0, cutoff_step_index=None):
|
| 23 |
+
super().__init__()
|
| 24 |
+
|
| 25 |
+
if (cutoff_step_ratio is None and cutoff_step_index is None) or (
|
| 26 |
+
cutoff_step_ratio is not None and cutoff_step_index is not None
|
| 27 |
+
):
|
| 28 |
+
raise ValueError("Either cutoff_step_ratio or cutoff_step_index should be provided, not both or none.")
|
| 29 |
+
|
| 30 |
+
if cutoff_step_ratio is not None and (
|
| 31 |
+
not isinstance(cutoff_step_ratio, float) or not (0.0 <= cutoff_step_ratio <= 1.0)
|
| 32 |
+
):
|
| 33 |
+
raise ValueError("cutoff_step_ratio must be a float between 0.0 and 1.0.")
|
| 34 |
+
|
| 35 |
+
@property
|
| 36 |
+
def tensor_inputs(self) -> List[str]:
|
| 37 |
+
raise NotImplementedError(f"You need to set the attribute `tensor_inputs` for {self.__class__}")
|
| 38 |
+
|
| 39 |
+
def callback_fn(self, pipeline, step_index, timesteps, callback_kwargs) -> Dict[str, Any]:
|
| 40 |
+
raise NotImplementedError(f"You need to implement the method `callback_fn` for {self.__class__}")
|
| 41 |
+
|
| 42 |
+
def __call__(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 43 |
+
return self.callback_fn(pipeline, step_index, timestep, callback_kwargs)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class MultiPipelineCallbacks:
|
| 47 |
+
"""
|
| 48 |
+
This class is designed to handle multiple pipeline callbacks. It accepts a list of PipelineCallback objects and
|
| 49 |
+
provides a unified interface for calling all of them.
|
| 50 |
+
"""
|
| 51 |
+
|
| 52 |
+
def __init__(self, callbacks: List[PipelineCallback]):
|
| 53 |
+
self.callbacks = callbacks
|
| 54 |
+
|
| 55 |
+
@property
|
| 56 |
+
def tensor_inputs(self) -> List[str]:
|
| 57 |
+
return [input for callback in self.callbacks for input in callback.tensor_inputs]
|
| 58 |
+
|
| 59 |
+
def __call__(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 60 |
+
"""
|
| 61 |
+
Calls all the callbacks in order with the given arguments and returns the final callback_kwargs.
|
| 62 |
+
"""
|
| 63 |
+
for callback in self.callbacks:
|
| 64 |
+
callback_kwargs = callback(pipeline, step_index, timestep, callback_kwargs)
|
| 65 |
+
|
| 66 |
+
return callback_kwargs
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
class SDCFGCutoffCallback(PipelineCallback):
|
| 70 |
+
"""
|
| 71 |
+
Callback function for Stable Diffusion Pipelines. After certain number of steps (set by `cutoff_step_ratio` or
|
| 72 |
+
`cutoff_step_index`), this callback will disable the CFG.
|
| 73 |
+
|
| 74 |
+
Note: This callback mutates the pipeline by changing the `_guidance_scale` attribute to 0.0 after the cutoff step.
|
| 75 |
+
"""
|
| 76 |
+
|
| 77 |
+
tensor_inputs = ["prompt_embeds"]
|
| 78 |
+
|
| 79 |
+
def callback_fn(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 80 |
+
cutoff_step_ratio = self.config.cutoff_step_ratio
|
| 81 |
+
cutoff_step_index = self.config.cutoff_step_index
|
| 82 |
+
|
| 83 |
+
# Use cutoff_step_index if it's not None, otherwise use cutoff_step_ratio
|
| 84 |
+
cutoff_step = (
|
| 85 |
+
cutoff_step_index if cutoff_step_index is not None else int(pipeline.num_timesteps * cutoff_step_ratio)
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
if step_index == cutoff_step:
|
| 89 |
+
prompt_embeds = callback_kwargs[self.tensor_inputs[0]]
|
| 90 |
+
prompt_embeds = prompt_embeds[-1:] # "-1" denotes the embeddings for conditional text tokens.
|
| 91 |
+
|
| 92 |
+
pipeline._guidance_scale = 0.0
|
| 93 |
+
|
| 94 |
+
callback_kwargs[self.tensor_inputs[0]] = prompt_embeds
|
| 95 |
+
return callback_kwargs
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
class SDXLCFGCutoffCallback(PipelineCallback):
|
| 99 |
+
"""
|
| 100 |
+
Callback function for the base Stable Diffusion XL Pipelines. After certain number of steps (set by
|
| 101 |
+
`cutoff_step_ratio` or `cutoff_step_index`), this callback will disable the CFG.
|
| 102 |
+
|
| 103 |
+
Note: This callback mutates the pipeline by changing the `_guidance_scale` attribute to 0.0 after the cutoff step.
|
| 104 |
+
"""
|
| 105 |
+
|
| 106 |
+
tensor_inputs = [
|
| 107 |
+
"prompt_embeds",
|
| 108 |
+
"add_text_embeds",
|
| 109 |
+
"add_time_ids",
|
| 110 |
+
]
|
| 111 |
+
|
| 112 |
+
def callback_fn(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 113 |
+
cutoff_step_ratio = self.config.cutoff_step_ratio
|
| 114 |
+
cutoff_step_index = self.config.cutoff_step_index
|
| 115 |
+
|
| 116 |
+
# Use cutoff_step_index if it's not None, otherwise use cutoff_step_ratio
|
| 117 |
+
cutoff_step = (
|
| 118 |
+
cutoff_step_index if cutoff_step_index is not None else int(pipeline.num_timesteps * cutoff_step_ratio)
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
if step_index == cutoff_step:
|
| 122 |
+
prompt_embeds = callback_kwargs[self.tensor_inputs[0]]
|
| 123 |
+
prompt_embeds = prompt_embeds[-1:] # "-1" denotes the embeddings for conditional text tokens.
|
| 124 |
+
|
| 125 |
+
add_text_embeds = callback_kwargs[self.tensor_inputs[1]]
|
| 126 |
+
add_text_embeds = add_text_embeds[-1:] # "-1" denotes the embeddings for conditional pooled text tokens
|
| 127 |
+
|
| 128 |
+
add_time_ids = callback_kwargs[self.tensor_inputs[2]]
|
| 129 |
+
add_time_ids = add_time_ids[-1:] # "-1" denotes the embeddings for conditional added time vector
|
| 130 |
+
|
| 131 |
+
pipeline._guidance_scale = 0.0
|
| 132 |
+
|
| 133 |
+
callback_kwargs[self.tensor_inputs[0]] = prompt_embeds
|
| 134 |
+
callback_kwargs[self.tensor_inputs[1]] = add_text_embeds
|
| 135 |
+
callback_kwargs[self.tensor_inputs[2]] = add_time_ids
|
| 136 |
+
|
| 137 |
+
return callback_kwargs
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
class SDXLControlnetCFGCutoffCallback(PipelineCallback):
|
| 141 |
+
"""
|
| 142 |
+
Callback function for the Controlnet Stable Diffusion XL Pipelines. After certain number of steps (set by
|
| 143 |
+
`cutoff_step_ratio` or `cutoff_step_index`), this callback will disable the CFG.
|
| 144 |
+
|
| 145 |
+
Note: This callback mutates the pipeline by changing the `_guidance_scale` attribute to 0.0 after the cutoff step.
|
| 146 |
+
"""
|
| 147 |
+
|
| 148 |
+
tensor_inputs = [
|
| 149 |
+
"prompt_embeds",
|
| 150 |
+
"add_text_embeds",
|
| 151 |
+
"add_time_ids",
|
| 152 |
+
"image",
|
| 153 |
+
]
|
| 154 |
+
|
| 155 |
+
def callback_fn(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 156 |
+
cutoff_step_ratio = self.config.cutoff_step_ratio
|
| 157 |
+
cutoff_step_index = self.config.cutoff_step_index
|
| 158 |
+
|
| 159 |
+
# Use cutoff_step_index if it's not None, otherwise use cutoff_step_ratio
|
| 160 |
+
cutoff_step = (
|
| 161 |
+
cutoff_step_index if cutoff_step_index is not None else int(pipeline.num_timesteps * cutoff_step_ratio)
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
if step_index == cutoff_step:
|
| 165 |
+
prompt_embeds = callback_kwargs[self.tensor_inputs[0]]
|
| 166 |
+
prompt_embeds = prompt_embeds[-1:] # "-1" denotes the embeddings for conditional text tokens.
|
| 167 |
+
|
| 168 |
+
add_text_embeds = callback_kwargs[self.tensor_inputs[1]]
|
| 169 |
+
add_text_embeds = add_text_embeds[-1:] # "-1" denotes the embeddings for conditional pooled text tokens
|
| 170 |
+
|
| 171 |
+
add_time_ids = callback_kwargs[self.tensor_inputs[2]]
|
| 172 |
+
add_time_ids = add_time_ids[-1:] # "-1" denotes the embeddings for conditional added time vector
|
| 173 |
+
|
| 174 |
+
# For Controlnet
|
| 175 |
+
image = callback_kwargs[self.tensor_inputs[3]]
|
| 176 |
+
image = image[-1:]
|
| 177 |
+
|
| 178 |
+
pipeline._guidance_scale = 0.0
|
| 179 |
+
|
| 180 |
+
callback_kwargs[self.tensor_inputs[0]] = prompt_embeds
|
| 181 |
+
callback_kwargs[self.tensor_inputs[1]] = add_text_embeds
|
| 182 |
+
callback_kwargs[self.tensor_inputs[2]] = add_time_ids
|
| 183 |
+
callback_kwargs[self.tensor_inputs[3]] = image
|
| 184 |
+
|
| 185 |
+
return callback_kwargs
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
class IPAdapterScaleCutoffCallback(PipelineCallback):
|
| 189 |
+
"""
|
| 190 |
+
Callback function for any pipeline that inherits `IPAdapterMixin`. After certain number of steps (set by
|
| 191 |
+
`cutoff_step_ratio` or `cutoff_step_index`), this callback will set the IP Adapter scale to `0.0`.
|
| 192 |
+
|
| 193 |
+
Note: This callback mutates the IP Adapter attention processors by setting the scale to 0.0 after the cutoff step.
|
| 194 |
+
"""
|
| 195 |
+
|
| 196 |
+
tensor_inputs = []
|
| 197 |
+
|
| 198 |
+
def callback_fn(self, pipeline, step_index, timestep, callback_kwargs) -> Dict[str, Any]:
|
| 199 |
+
cutoff_step_ratio = self.config.cutoff_step_ratio
|
| 200 |
+
cutoff_step_index = self.config.cutoff_step_index
|
| 201 |
+
|
| 202 |
+
# Use cutoff_step_index if it's not None, otherwise use cutoff_step_ratio
|
| 203 |
+
cutoff_step = (
|
| 204 |
+
cutoff_step_index if cutoff_step_index is not None else int(pipeline.num_timesteps * cutoff_step_ratio)
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
if step_index == cutoff_step:
|
| 208 |
+
pipeline.set_ip_adapter_scale(0.0)
|
| 209 |
+
return callback_kwargs
|
venv/lib/python3.10/site-packages/diffusers/configuration_utils.py
ADDED
|
@@ -0,0 +1,760 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
"""ConfigMixin base class and utilities."""
|
| 17 |
+
|
| 18 |
+
import dataclasses
|
| 19 |
+
import functools
|
| 20 |
+
import importlib
|
| 21 |
+
import inspect
|
| 22 |
+
import json
|
| 23 |
+
import os
|
| 24 |
+
import re
|
| 25 |
+
from collections import OrderedDict
|
| 26 |
+
from pathlib import Path
|
| 27 |
+
from typing import Any, Dict, Optional, Tuple, Union
|
| 28 |
+
|
| 29 |
+
import numpy as np
|
| 30 |
+
from huggingface_hub import DDUFEntry, create_repo, hf_hub_download
|
| 31 |
+
from huggingface_hub.utils import (
|
| 32 |
+
EntryNotFoundError,
|
| 33 |
+
RepositoryNotFoundError,
|
| 34 |
+
RevisionNotFoundError,
|
| 35 |
+
validate_hf_hub_args,
|
| 36 |
+
)
|
| 37 |
+
from requests import HTTPError
|
| 38 |
+
from typing_extensions import Self
|
| 39 |
+
|
| 40 |
+
from . import __version__
|
| 41 |
+
from .utils import (
|
| 42 |
+
HUGGINGFACE_CO_RESOLVE_ENDPOINT,
|
| 43 |
+
DummyObject,
|
| 44 |
+
deprecate,
|
| 45 |
+
extract_commit_hash,
|
| 46 |
+
http_user_agent,
|
| 47 |
+
logging,
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
logger = logging.get_logger(__name__)
|
| 52 |
+
|
| 53 |
+
_re_configuration_file = re.compile(r"config\.(.*)\.json")
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class FrozenDict(OrderedDict):
|
| 57 |
+
def __init__(self, *args, **kwargs):
|
| 58 |
+
super().__init__(*args, **kwargs)
|
| 59 |
+
|
| 60 |
+
for key, value in self.items():
|
| 61 |
+
setattr(self, key, value)
|
| 62 |
+
|
| 63 |
+
self.__frozen = True
|
| 64 |
+
|
| 65 |
+
def __delitem__(self, *args, **kwargs):
|
| 66 |
+
raise Exception(f"You cannot use ``__delitem__`` on a {self.__class__.__name__} instance.")
|
| 67 |
+
|
| 68 |
+
def setdefault(self, *args, **kwargs):
|
| 69 |
+
raise Exception(f"You cannot use ``setdefault`` on a {self.__class__.__name__} instance.")
|
| 70 |
+
|
| 71 |
+
def pop(self, *args, **kwargs):
|
| 72 |
+
raise Exception(f"You cannot use ``pop`` on a {self.__class__.__name__} instance.")
|
| 73 |
+
|
| 74 |
+
def update(self, *args, **kwargs):
|
| 75 |
+
raise Exception(f"You cannot use ``update`` on a {self.__class__.__name__} instance.")
|
| 76 |
+
|
| 77 |
+
def __setattr__(self, name, value):
|
| 78 |
+
if hasattr(self, "__frozen") and self.__frozen:
|
| 79 |
+
raise Exception(f"You cannot use ``__setattr__`` on a {self.__class__.__name__} instance.")
|
| 80 |
+
super().__setattr__(name, value)
|
| 81 |
+
|
| 82 |
+
def __setitem__(self, name, value):
|
| 83 |
+
if hasattr(self, "__frozen") and self.__frozen:
|
| 84 |
+
raise Exception(f"You cannot use ``__setattr__`` on a {self.__class__.__name__} instance.")
|
| 85 |
+
super().__setitem__(name, value)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
class ConfigMixin:
|
| 89 |
+
r"""
|
| 90 |
+
Base class for all configuration classes. All configuration parameters are stored under `self.config`. Also
|
| 91 |
+
provides the [`~ConfigMixin.from_config`] and [`~ConfigMixin.save_config`] methods for loading, downloading, and
|
| 92 |
+
saving classes that inherit from [`ConfigMixin`].
|
| 93 |
+
|
| 94 |
+
Class attributes:
|
| 95 |
+
- **config_name** (`str`) -- A filename under which the config should stored when calling
|
| 96 |
+
[`~ConfigMixin.save_config`] (should be overridden by parent class).
|
| 97 |
+
- **ignore_for_config** (`List[str]`) -- A list of attributes that should not be saved in the config (should be
|
| 98 |
+
overridden by subclass).
|
| 99 |
+
- **has_compatibles** (`bool`) -- Whether the class has compatible classes (should be overridden by subclass).
|
| 100 |
+
- **_deprecated_kwargs** (`List[str]`) -- Keyword arguments that are deprecated. Note that the `init` function
|
| 101 |
+
should only have a `kwargs` argument if at least one argument is deprecated (should be overridden by
|
| 102 |
+
subclass).
|
| 103 |
+
"""
|
| 104 |
+
|
| 105 |
+
config_name = None
|
| 106 |
+
ignore_for_config = []
|
| 107 |
+
has_compatibles = False
|
| 108 |
+
|
| 109 |
+
_deprecated_kwargs = []
|
| 110 |
+
|
| 111 |
+
def register_to_config(self, **kwargs):
|
| 112 |
+
if self.config_name is None:
|
| 113 |
+
raise NotImplementedError(f"Make sure that {self.__class__} has defined a class name `config_name`")
|
| 114 |
+
# Special case for `kwargs` used in deprecation warning added to schedulers
|
| 115 |
+
# TODO: remove this when we remove the deprecation warning, and the `kwargs` argument,
|
| 116 |
+
# or solve in a more general way.
|
| 117 |
+
kwargs.pop("kwargs", None)
|
| 118 |
+
|
| 119 |
+
if not hasattr(self, "_internal_dict"):
|
| 120 |
+
internal_dict = kwargs
|
| 121 |
+
else:
|
| 122 |
+
previous_dict = dict(self._internal_dict)
|
| 123 |
+
internal_dict = {**self._internal_dict, **kwargs}
|
| 124 |
+
logger.debug(f"Updating config from {previous_dict} to {internal_dict}")
|
| 125 |
+
|
| 126 |
+
self._internal_dict = FrozenDict(internal_dict)
|
| 127 |
+
|
| 128 |
+
def __getattr__(self, name: str) -> Any:
|
| 129 |
+
"""The only reason we overwrite `getattr` here is to gracefully deprecate accessing
|
| 130 |
+
config attributes directly. See https://github.com/huggingface/diffusers/pull/3129
|
| 131 |
+
|
| 132 |
+
This function is mostly copied from PyTorch's __getattr__ overwrite:
|
| 133 |
+
https://pytorch.org/docs/stable/_modules/torch/nn/modules/module.html#Module
|
| 134 |
+
"""
|
| 135 |
+
|
| 136 |
+
is_in_config = "_internal_dict" in self.__dict__ and hasattr(self.__dict__["_internal_dict"], name)
|
| 137 |
+
is_attribute = name in self.__dict__
|
| 138 |
+
|
| 139 |
+
if is_in_config and not is_attribute:
|
| 140 |
+
deprecation_message = f"Accessing config attribute `{name}` directly via '{type(self).__name__}' object attribute is deprecated. Please access '{name}' over '{type(self).__name__}'s config object instead, e.g. 'scheduler.config.{name}'."
|
| 141 |
+
deprecate("direct config name access", "1.0.0", deprecation_message, standard_warn=False)
|
| 142 |
+
return self._internal_dict[name]
|
| 143 |
+
|
| 144 |
+
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
|
| 145 |
+
|
| 146 |
+
def save_config(self, save_directory: Union[str, os.PathLike], push_to_hub: bool = False, **kwargs):
|
| 147 |
+
"""
|
| 148 |
+
Save a configuration object to the directory specified in `save_directory` so that it can be reloaded using the
|
| 149 |
+
[`~ConfigMixin.from_config`] class method.
|
| 150 |
+
|
| 151 |
+
Args:
|
| 152 |
+
save_directory (`str` or `os.PathLike`):
|
| 153 |
+
Directory where the configuration JSON file is saved (will be created if it does not exist).
|
| 154 |
+
push_to_hub (`bool`, *optional*, defaults to `False`):
|
| 155 |
+
Whether or not to push your model to the Hugging Face Hub after saving it. You can specify the
|
| 156 |
+
repository you want to push to with `repo_id` (will default to the name of `save_directory` in your
|
| 157 |
+
namespace).
|
| 158 |
+
kwargs (`Dict[str, Any]`, *optional*):
|
| 159 |
+
Additional keyword arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
|
| 160 |
+
"""
|
| 161 |
+
if os.path.isfile(save_directory):
|
| 162 |
+
raise AssertionError(f"Provided path ({save_directory}) should be a directory, not a file")
|
| 163 |
+
|
| 164 |
+
os.makedirs(save_directory, exist_ok=True)
|
| 165 |
+
|
| 166 |
+
# If we save using the predefined names, we can load using `from_config`
|
| 167 |
+
output_config_file = os.path.join(save_directory, self.config_name)
|
| 168 |
+
|
| 169 |
+
self.to_json_file(output_config_file)
|
| 170 |
+
logger.info(f"Configuration saved in {output_config_file}")
|
| 171 |
+
|
| 172 |
+
if push_to_hub:
|
| 173 |
+
commit_message = kwargs.pop("commit_message", None)
|
| 174 |
+
private = kwargs.pop("private", None)
|
| 175 |
+
create_pr = kwargs.pop("create_pr", False)
|
| 176 |
+
token = kwargs.pop("token", None)
|
| 177 |
+
repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1])
|
| 178 |
+
repo_id = create_repo(repo_id, exist_ok=True, private=private, token=token).repo_id
|
| 179 |
+
|
| 180 |
+
self._upload_folder(
|
| 181 |
+
save_directory,
|
| 182 |
+
repo_id,
|
| 183 |
+
token=token,
|
| 184 |
+
commit_message=commit_message,
|
| 185 |
+
create_pr=create_pr,
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
@classmethod
|
| 189 |
+
def from_config(
|
| 190 |
+
cls, config: Union[FrozenDict, Dict[str, Any]] = None, return_unused_kwargs=False, **kwargs
|
| 191 |
+
) -> Union[Self, Tuple[Self, Dict[str, Any]]]:
|
| 192 |
+
r"""
|
| 193 |
+
Instantiate a Python class from a config dictionary.
|
| 194 |
+
|
| 195 |
+
Parameters:
|
| 196 |
+
config (`Dict[str, Any]`):
|
| 197 |
+
A config dictionary from which the Python class is instantiated. Make sure to only load configuration
|
| 198 |
+
files of compatible classes.
|
| 199 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False`):
|
| 200 |
+
Whether kwargs that are not consumed by the Python class should be returned or not.
|
| 201 |
+
kwargs (remaining dictionary of keyword arguments, *optional*):
|
| 202 |
+
Can be used to update the configuration object (after it is loaded) and initiate the Python class.
|
| 203 |
+
`**kwargs` are passed directly to the underlying scheduler/model's `__init__` method and eventually
|
| 204 |
+
overwrite the same named arguments in `config`.
|
| 205 |
+
|
| 206 |
+
Returns:
|
| 207 |
+
[`ModelMixin`] or [`SchedulerMixin`]:
|
| 208 |
+
A model or scheduler object instantiated from a config dictionary.
|
| 209 |
+
|
| 210 |
+
Examples:
|
| 211 |
+
|
| 212 |
+
```python
|
| 213 |
+
>>> from diffusers import DDPMScheduler, DDIMScheduler, PNDMScheduler
|
| 214 |
+
|
| 215 |
+
>>> # Download scheduler from huggingface.co and cache.
|
| 216 |
+
>>> scheduler = DDPMScheduler.from_pretrained("google/ddpm-cifar10-32")
|
| 217 |
+
|
| 218 |
+
>>> # Instantiate DDIM scheduler class with same config as DDPM
|
| 219 |
+
>>> scheduler = DDIMScheduler.from_config(scheduler.config)
|
| 220 |
+
|
| 221 |
+
>>> # Instantiate PNDM scheduler class with same config as DDPM
|
| 222 |
+
>>> scheduler = PNDMScheduler.from_config(scheduler.config)
|
| 223 |
+
```
|
| 224 |
+
"""
|
| 225 |
+
# <===== TO BE REMOVED WITH DEPRECATION
|
| 226 |
+
# TODO(Patrick) - make sure to remove the following lines when config=="model_path" is deprecated
|
| 227 |
+
if "pretrained_model_name_or_path" in kwargs:
|
| 228 |
+
config = kwargs.pop("pretrained_model_name_or_path")
|
| 229 |
+
|
| 230 |
+
if config is None:
|
| 231 |
+
raise ValueError("Please make sure to provide a config as the first positional argument.")
|
| 232 |
+
# ======>
|
| 233 |
+
|
| 234 |
+
if not isinstance(config, dict):
|
| 235 |
+
deprecation_message = "It is deprecated to pass a pretrained model name or path to `from_config`."
|
| 236 |
+
if "Scheduler" in cls.__name__:
|
| 237 |
+
deprecation_message += (
|
| 238 |
+
f"If you were trying to load a scheduler, please use {cls}.from_pretrained(...) instead."
|
| 239 |
+
" Otherwise, please make sure to pass a configuration dictionary instead. This functionality will"
|
| 240 |
+
" be removed in v1.0.0."
|
| 241 |
+
)
|
| 242 |
+
elif "Model" in cls.__name__:
|
| 243 |
+
deprecation_message += (
|
| 244 |
+
f"If you were trying to load a model, please use {cls}.load_config(...) followed by"
|
| 245 |
+
f" {cls}.from_config(...) instead. Otherwise, please make sure to pass a configuration dictionary"
|
| 246 |
+
" instead. This functionality will be removed in v1.0.0."
|
| 247 |
+
)
|
| 248 |
+
deprecate("config-passed-as-path", "1.0.0", deprecation_message, standard_warn=False)
|
| 249 |
+
config, kwargs = cls.load_config(pretrained_model_name_or_path=config, return_unused_kwargs=True, **kwargs)
|
| 250 |
+
|
| 251 |
+
init_dict, unused_kwargs, hidden_dict = cls.extract_init_dict(config, **kwargs)
|
| 252 |
+
|
| 253 |
+
# Allow dtype to be specified on initialization
|
| 254 |
+
if "dtype" in unused_kwargs:
|
| 255 |
+
init_dict["dtype"] = unused_kwargs.pop("dtype")
|
| 256 |
+
|
| 257 |
+
# add possible deprecated kwargs
|
| 258 |
+
for deprecated_kwarg in cls._deprecated_kwargs:
|
| 259 |
+
if deprecated_kwarg in unused_kwargs:
|
| 260 |
+
init_dict[deprecated_kwarg] = unused_kwargs.pop(deprecated_kwarg)
|
| 261 |
+
|
| 262 |
+
# Return model and optionally state and/or unused_kwargs
|
| 263 |
+
model = cls(**init_dict)
|
| 264 |
+
|
| 265 |
+
# make sure to also save config parameters that might be used for compatible classes
|
| 266 |
+
# update _class_name
|
| 267 |
+
if "_class_name" in hidden_dict:
|
| 268 |
+
hidden_dict["_class_name"] = cls.__name__
|
| 269 |
+
|
| 270 |
+
model.register_to_config(**hidden_dict)
|
| 271 |
+
|
| 272 |
+
# add hidden kwargs of compatible classes to unused_kwargs
|
| 273 |
+
unused_kwargs = {**unused_kwargs, **hidden_dict}
|
| 274 |
+
|
| 275 |
+
if return_unused_kwargs:
|
| 276 |
+
return (model, unused_kwargs)
|
| 277 |
+
else:
|
| 278 |
+
return model
|
| 279 |
+
|
| 280 |
+
@classmethod
|
| 281 |
+
def get_config_dict(cls, *args, **kwargs):
|
| 282 |
+
deprecation_message = (
|
| 283 |
+
f" The function get_config_dict is deprecated. Please use {cls}.load_config instead. This function will be"
|
| 284 |
+
" removed in version v1.0.0"
|
| 285 |
+
)
|
| 286 |
+
deprecate("get_config_dict", "1.0.0", deprecation_message, standard_warn=False)
|
| 287 |
+
return cls.load_config(*args, **kwargs)
|
| 288 |
+
|
| 289 |
+
@classmethod
|
| 290 |
+
@validate_hf_hub_args
|
| 291 |
+
def load_config(
|
| 292 |
+
cls,
|
| 293 |
+
pretrained_model_name_or_path: Union[str, os.PathLike],
|
| 294 |
+
return_unused_kwargs=False,
|
| 295 |
+
return_commit_hash=False,
|
| 296 |
+
**kwargs,
|
| 297 |
+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
| 298 |
+
r"""
|
| 299 |
+
Load a model or scheduler configuration.
|
| 300 |
+
|
| 301 |
+
Parameters:
|
| 302 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`, *optional*):
|
| 303 |
+
Can be either:
|
| 304 |
+
|
| 305 |
+
- A string, the *model id* (for example `google/ddpm-celebahq-256`) of a pretrained model hosted on
|
| 306 |
+
the Hub.
|
| 307 |
+
- A path to a *directory* (for example `./my_model_directory`) containing model weights saved with
|
| 308 |
+
[`~ConfigMixin.save_config`].
|
| 309 |
+
|
| 310 |
+
cache_dir (`Union[str, os.PathLike]`, *optional*):
|
| 311 |
+
Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
|
| 312 |
+
is not used.
|
| 313 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 314 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 315 |
+
cached versions if they exist.
|
| 316 |
+
proxies (`Dict[str, str]`, *optional*):
|
| 317 |
+
A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
|
| 318 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 319 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 320 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 321 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 322 |
+
Whether to only load local model weights and configuration files or not. If set to `True`, the model
|
| 323 |
+
won't be downloaded from the Hub.
|
| 324 |
+
token (`str` or *bool*, *optional*):
|
| 325 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
|
| 326 |
+
`diffusers-cli login` (stored in `~/.huggingface`) is used.
|
| 327 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 328 |
+
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
| 329 |
+
allowed by Git.
|
| 330 |
+
subfolder (`str`, *optional*, defaults to `""`):
|
| 331 |
+
The subfolder location of a model file within a larger model repository on the Hub or locally.
|
| 332 |
+
return_unused_kwargs (`bool`, *optional*, defaults to `False):
|
| 333 |
+
Whether unused keyword arguments of the config are returned.
|
| 334 |
+
return_commit_hash (`bool`, *optional*, defaults to `False):
|
| 335 |
+
Whether the `commit_hash` of the loaded configuration are returned.
|
| 336 |
+
|
| 337 |
+
Returns:
|
| 338 |
+
`dict`:
|
| 339 |
+
A dictionary of all the parameters stored in a JSON configuration file.
|
| 340 |
+
|
| 341 |
+
"""
|
| 342 |
+
cache_dir = kwargs.pop("cache_dir", None)
|
| 343 |
+
local_dir = kwargs.pop("local_dir", None)
|
| 344 |
+
local_dir_use_symlinks = kwargs.pop("local_dir_use_symlinks", "auto")
|
| 345 |
+
force_download = kwargs.pop("force_download", False)
|
| 346 |
+
proxies = kwargs.pop("proxies", None)
|
| 347 |
+
token = kwargs.pop("token", None)
|
| 348 |
+
local_files_only = kwargs.pop("local_files_only", False)
|
| 349 |
+
revision = kwargs.pop("revision", None)
|
| 350 |
+
_ = kwargs.pop("mirror", None)
|
| 351 |
+
subfolder = kwargs.pop("subfolder", None)
|
| 352 |
+
user_agent = kwargs.pop("user_agent", {})
|
| 353 |
+
dduf_entries: Optional[Dict[str, DDUFEntry]] = kwargs.pop("dduf_entries", None)
|
| 354 |
+
|
| 355 |
+
user_agent = {**user_agent, "file_type": "config"}
|
| 356 |
+
user_agent = http_user_agent(user_agent)
|
| 357 |
+
|
| 358 |
+
pretrained_model_name_or_path = str(pretrained_model_name_or_path)
|
| 359 |
+
|
| 360 |
+
if cls.config_name is None:
|
| 361 |
+
raise ValueError(
|
| 362 |
+
"`self.config_name` is not defined. Note that one should not load a config from "
|
| 363 |
+
"`ConfigMixin`. Please make sure to define `config_name` in a class inheriting from `ConfigMixin`"
|
| 364 |
+
)
|
| 365 |
+
# Custom path for now
|
| 366 |
+
if dduf_entries:
|
| 367 |
+
if subfolder is not None:
|
| 368 |
+
raise ValueError(
|
| 369 |
+
"DDUF file only allow for 1 level of directory (e.g transformer/model1/model.safetentors is not allowed). "
|
| 370 |
+
"Please check the DDUF structure"
|
| 371 |
+
)
|
| 372 |
+
config_file = cls._get_config_file_from_dduf(pretrained_model_name_or_path, dduf_entries)
|
| 373 |
+
elif os.path.isfile(pretrained_model_name_or_path):
|
| 374 |
+
config_file = pretrained_model_name_or_path
|
| 375 |
+
elif os.path.isdir(pretrained_model_name_or_path):
|
| 376 |
+
if subfolder is not None and os.path.isfile(
|
| 377 |
+
os.path.join(pretrained_model_name_or_path, subfolder, cls.config_name)
|
| 378 |
+
):
|
| 379 |
+
config_file = os.path.join(pretrained_model_name_or_path, subfolder, cls.config_name)
|
| 380 |
+
elif os.path.isfile(os.path.join(pretrained_model_name_or_path, cls.config_name)):
|
| 381 |
+
# Load from a PyTorch checkpoint
|
| 382 |
+
config_file = os.path.join(pretrained_model_name_or_path, cls.config_name)
|
| 383 |
+
else:
|
| 384 |
+
raise EnvironmentError(
|
| 385 |
+
f"Error no file named {cls.config_name} found in directory {pretrained_model_name_or_path}."
|
| 386 |
+
)
|
| 387 |
+
else:
|
| 388 |
+
try:
|
| 389 |
+
# Load from URL or cache if already cached
|
| 390 |
+
config_file = hf_hub_download(
|
| 391 |
+
pretrained_model_name_or_path,
|
| 392 |
+
filename=cls.config_name,
|
| 393 |
+
cache_dir=cache_dir,
|
| 394 |
+
force_download=force_download,
|
| 395 |
+
proxies=proxies,
|
| 396 |
+
local_files_only=local_files_only,
|
| 397 |
+
token=token,
|
| 398 |
+
user_agent=user_agent,
|
| 399 |
+
subfolder=subfolder,
|
| 400 |
+
revision=revision,
|
| 401 |
+
local_dir=local_dir,
|
| 402 |
+
local_dir_use_symlinks=local_dir_use_symlinks,
|
| 403 |
+
)
|
| 404 |
+
except RepositoryNotFoundError:
|
| 405 |
+
raise EnvironmentError(
|
| 406 |
+
f"{pretrained_model_name_or_path} is not a local folder and is not a valid model identifier"
|
| 407 |
+
" listed on 'https://huggingface.co/models'\nIf this is a private repository, make sure to pass a"
|
| 408 |
+
" token having permission to this repo with `token` or log in with `huggingface-cli login`."
|
| 409 |
+
)
|
| 410 |
+
except RevisionNotFoundError:
|
| 411 |
+
raise EnvironmentError(
|
| 412 |
+
f"{revision} is not a valid git identifier (branch name, tag name or commit id) that exists for"
|
| 413 |
+
" this model name. Check the model page at"
|
| 414 |
+
f" 'https://huggingface.co/{pretrained_model_name_or_path}' for available revisions."
|
| 415 |
+
)
|
| 416 |
+
except EntryNotFoundError:
|
| 417 |
+
raise EnvironmentError(
|
| 418 |
+
f"{pretrained_model_name_or_path} does not appear to have a file named {cls.config_name}."
|
| 419 |
+
)
|
| 420 |
+
except HTTPError as err:
|
| 421 |
+
raise EnvironmentError(
|
| 422 |
+
"There was a specific connection error when trying to load"
|
| 423 |
+
f" {pretrained_model_name_or_path}:\n{err}"
|
| 424 |
+
)
|
| 425 |
+
except ValueError:
|
| 426 |
+
raise EnvironmentError(
|
| 427 |
+
f"We couldn't connect to '{HUGGINGFACE_CO_RESOLVE_ENDPOINT}' to load this model, couldn't find it"
|
| 428 |
+
f" in the cached files and it looks like {pretrained_model_name_or_path} is not the path to a"
|
| 429 |
+
f" directory containing a {cls.config_name} file.\nCheckout your internet connection or see how to"
|
| 430 |
+
" run the library in offline mode at"
|
| 431 |
+
" 'https://huggingface.co/docs/diffusers/installation#offline-mode'."
|
| 432 |
+
)
|
| 433 |
+
except EnvironmentError:
|
| 434 |
+
raise EnvironmentError(
|
| 435 |
+
f"Can't load config for '{pretrained_model_name_or_path}'. If you were trying to load it from "
|
| 436 |
+
"'https://huggingface.co/models', make sure you don't have a local directory with the same name. "
|
| 437 |
+
f"Otherwise, make sure '{pretrained_model_name_or_path}' is the correct path to a directory "
|
| 438 |
+
f"containing a {cls.config_name} file"
|
| 439 |
+
)
|
| 440 |
+
try:
|
| 441 |
+
config_dict = cls._dict_from_json_file(config_file, dduf_entries=dduf_entries)
|
| 442 |
+
|
| 443 |
+
commit_hash = extract_commit_hash(config_file)
|
| 444 |
+
except (json.JSONDecodeError, UnicodeDecodeError):
|
| 445 |
+
raise EnvironmentError(f"It looks like the config file at '{config_file}' is not a valid JSON file.")
|
| 446 |
+
|
| 447 |
+
if not (return_unused_kwargs or return_commit_hash):
|
| 448 |
+
return config_dict
|
| 449 |
+
|
| 450 |
+
outputs = (config_dict,)
|
| 451 |
+
|
| 452 |
+
if return_unused_kwargs:
|
| 453 |
+
outputs += (kwargs,)
|
| 454 |
+
|
| 455 |
+
if return_commit_hash:
|
| 456 |
+
outputs += (commit_hash,)
|
| 457 |
+
|
| 458 |
+
return outputs
|
| 459 |
+
|
| 460 |
+
@staticmethod
|
| 461 |
+
def _get_init_keys(input_class):
|
| 462 |
+
return set(dict(inspect.signature(input_class.__init__).parameters).keys())
|
| 463 |
+
|
| 464 |
+
@classmethod
|
| 465 |
+
def extract_init_dict(cls, config_dict, **kwargs):
|
| 466 |
+
# Skip keys that were not present in the original config, so default __init__ values were used
|
| 467 |
+
used_defaults = config_dict.get("_use_default_values", [])
|
| 468 |
+
config_dict = {k: v for k, v in config_dict.items() if k not in used_defaults and k != "_use_default_values"}
|
| 469 |
+
|
| 470 |
+
# 0. Copy origin config dict
|
| 471 |
+
original_dict = dict(config_dict.items())
|
| 472 |
+
|
| 473 |
+
# 1. Retrieve expected config attributes from __init__ signature
|
| 474 |
+
expected_keys = cls._get_init_keys(cls)
|
| 475 |
+
expected_keys.remove("self")
|
| 476 |
+
# remove general kwargs if present in dict
|
| 477 |
+
if "kwargs" in expected_keys:
|
| 478 |
+
expected_keys.remove("kwargs")
|
| 479 |
+
# remove flax internal keys
|
| 480 |
+
if hasattr(cls, "_flax_internal_args"):
|
| 481 |
+
for arg in cls._flax_internal_args:
|
| 482 |
+
expected_keys.remove(arg)
|
| 483 |
+
|
| 484 |
+
# 2. Remove attributes that cannot be expected from expected config attributes
|
| 485 |
+
# remove keys to be ignored
|
| 486 |
+
if len(cls.ignore_for_config) > 0:
|
| 487 |
+
expected_keys = expected_keys - set(cls.ignore_for_config)
|
| 488 |
+
|
| 489 |
+
# load diffusers library to import compatible and original scheduler
|
| 490 |
+
diffusers_library = importlib.import_module(__name__.split(".")[0])
|
| 491 |
+
|
| 492 |
+
if cls.has_compatibles:
|
| 493 |
+
compatible_classes = [c for c in cls._get_compatibles() if not isinstance(c, DummyObject)]
|
| 494 |
+
else:
|
| 495 |
+
compatible_classes = []
|
| 496 |
+
|
| 497 |
+
expected_keys_comp_cls = set()
|
| 498 |
+
for c in compatible_classes:
|
| 499 |
+
expected_keys_c = cls._get_init_keys(c)
|
| 500 |
+
expected_keys_comp_cls = expected_keys_comp_cls.union(expected_keys_c)
|
| 501 |
+
expected_keys_comp_cls = expected_keys_comp_cls - cls._get_init_keys(cls)
|
| 502 |
+
config_dict = {k: v for k, v in config_dict.items() if k not in expected_keys_comp_cls}
|
| 503 |
+
|
| 504 |
+
# remove attributes from orig class that cannot be expected
|
| 505 |
+
orig_cls_name = config_dict.pop("_class_name", cls.__name__)
|
| 506 |
+
if (
|
| 507 |
+
isinstance(orig_cls_name, str)
|
| 508 |
+
and orig_cls_name != cls.__name__
|
| 509 |
+
and hasattr(diffusers_library, orig_cls_name)
|
| 510 |
+
):
|
| 511 |
+
orig_cls = getattr(diffusers_library, orig_cls_name)
|
| 512 |
+
unexpected_keys_from_orig = cls._get_init_keys(orig_cls) - expected_keys
|
| 513 |
+
config_dict = {k: v for k, v in config_dict.items() if k not in unexpected_keys_from_orig}
|
| 514 |
+
elif not isinstance(orig_cls_name, str) and not isinstance(orig_cls_name, (list, tuple)):
|
| 515 |
+
raise ValueError(
|
| 516 |
+
"Make sure that the `_class_name` is of type string or list of string (for custom pipelines)."
|
| 517 |
+
)
|
| 518 |
+
|
| 519 |
+
# remove private attributes
|
| 520 |
+
config_dict = {k: v for k, v in config_dict.items() if not k.startswith("_")}
|
| 521 |
+
|
| 522 |
+
# remove quantization_config
|
| 523 |
+
config_dict = {k: v for k, v in config_dict.items() if k != "quantization_config"}
|
| 524 |
+
|
| 525 |
+
# 3. Create keyword arguments that will be passed to __init__ from expected keyword arguments
|
| 526 |
+
init_dict = {}
|
| 527 |
+
for key in expected_keys:
|
| 528 |
+
# if config param is passed to kwarg and is present in config dict
|
| 529 |
+
# it should overwrite existing config dict key
|
| 530 |
+
if key in kwargs and key in config_dict:
|
| 531 |
+
config_dict[key] = kwargs.pop(key)
|
| 532 |
+
|
| 533 |
+
if key in kwargs:
|
| 534 |
+
# overwrite key
|
| 535 |
+
init_dict[key] = kwargs.pop(key)
|
| 536 |
+
elif key in config_dict:
|
| 537 |
+
# use value from config dict
|
| 538 |
+
init_dict[key] = config_dict.pop(key)
|
| 539 |
+
|
| 540 |
+
# 4. Give nice warning if unexpected values have been passed
|
| 541 |
+
if len(config_dict) > 0:
|
| 542 |
+
logger.warning(
|
| 543 |
+
f"The config attributes {config_dict} were passed to {cls.__name__}, "
|
| 544 |
+
"but are not expected and will be ignored. Please verify your "
|
| 545 |
+
f"{cls.config_name} configuration file."
|
| 546 |
+
)
|
| 547 |
+
|
| 548 |
+
# 5. Give nice info if config attributes are initialized to default because they have not been passed
|
| 549 |
+
passed_keys = set(init_dict.keys())
|
| 550 |
+
if len(expected_keys - passed_keys) > 0:
|
| 551 |
+
logger.info(
|
| 552 |
+
f"{expected_keys - passed_keys} was not found in config. Values will be initialized to default values."
|
| 553 |
+
)
|
| 554 |
+
|
| 555 |
+
# 6. Define unused keyword arguments
|
| 556 |
+
unused_kwargs = {**config_dict, **kwargs}
|
| 557 |
+
|
| 558 |
+
# 7. Define "hidden" config parameters that were saved for compatible classes
|
| 559 |
+
hidden_config_dict = {k: v for k, v in original_dict.items() if k not in init_dict}
|
| 560 |
+
|
| 561 |
+
return init_dict, unused_kwargs, hidden_config_dict
|
| 562 |
+
|
| 563 |
+
@classmethod
|
| 564 |
+
def _dict_from_json_file(
|
| 565 |
+
cls, json_file: Union[str, os.PathLike], dduf_entries: Optional[Dict[str, DDUFEntry]] = None
|
| 566 |
+
):
|
| 567 |
+
if dduf_entries:
|
| 568 |
+
text = dduf_entries[json_file].read_text()
|
| 569 |
+
else:
|
| 570 |
+
with open(json_file, "r", encoding="utf-8") as reader:
|
| 571 |
+
text = reader.read()
|
| 572 |
+
return json.loads(text)
|
| 573 |
+
|
| 574 |
+
def __repr__(self):
|
| 575 |
+
return f"{self.__class__.__name__} {self.to_json_string()}"
|
| 576 |
+
|
| 577 |
+
@property
|
| 578 |
+
def config(self) -> Dict[str, Any]:
|
| 579 |
+
"""
|
| 580 |
+
Returns the config of the class as a frozen dictionary
|
| 581 |
+
|
| 582 |
+
Returns:
|
| 583 |
+
`Dict[str, Any]`: Config of the class.
|
| 584 |
+
"""
|
| 585 |
+
return self._internal_dict
|
| 586 |
+
|
| 587 |
+
def to_json_string(self) -> str:
|
| 588 |
+
"""
|
| 589 |
+
Serializes the configuration instance to a JSON string.
|
| 590 |
+
|
| 591 |
+
Returns:
|
| 592 |
+
`str`:
|
| 593 |
+
String containing all the attributes that make up the configuration instance in JSON format.
|
| 594 |
+
"""
|
| 595 |
+
config_dict = self._internal_dict if hasattr(self, "_internal_dict") else {}
|
| 596 |
+
config_dict["_class_name"] = self.__class__.__name__
|
| 597 |
+
config_dict["_diffusers_version"] = __version__
|
| 598 |
+
|
| 599 |
+
def to_json_saveable(value):
|
| 600 |
+
if isinstance(value, np.ndarray):
|
| 601 |
+
value = value.tolist()
|
| 602 |
+
elif isinstance(value, Path):
|
| 603 |
+
value = value.as_posix()
|
| 604 |
+
return value
|
| 605 |
+
|
| 606 |
+
if "quantization_config" in config_dict:
|
| 607 |
+
config_dict["quantization_config"] = (
|
| 608 |
+
config_dict.quantization_config.to_dict()
|
| 609 |
+
if not isinstance(config_dict.quantization_config, dict)
|
| 610 |
+
else config_dict.quantization_config
|
| 611 |
+
)
|
| 612 |
+
|
| 613 |
+
config_dict = {k: to_json_saveable(v) for k, v in config_dict.items()}
|
| 614 |
+
# Don't save "_ignore_files" or "_use_default_values"
|
| 615 |
+
config_dict.pop("_ignore_files", None)
|
| 616 |
+
config_dict.pop("_use_default_values", None)
|
| 617 |
+
# pop the `_pre_quantization_dtype` as torch.dtypes are not serializable.
|
| 618 |
+
_ = config_dict.pop("_pre_quantization_dtype", None)
|
| 619 |
+
|
| 620 |
+
return json.dumps(config_dict, indent=2, sort_keys=True) + "\n"
|
| 621 |
+
|
| 622 |
+
def to_json_file(self, json_file_path: Union[str, os.PathLike]):
|
| 623 |
+
"""
|
| 624 |
+
Save the configuration instance's parameters to a JSON file.
|
| 625 |
+
|
| 626 |
+
Args:
|
| 627 |
+
json_file_path (`str` or `os.PathLike`):
|
| 628 |
+
Path to the JSON file to save a configuration instance's parameters.
|
| 629 |
+
"""
|
| 630 |
+
with open(json_file_path, "w", encoding="utf-8") as writer:
|
| 631 |
+
writer.write(self.to_json_string())
|
| 632 |
+
|
| 633 |
+
@classmethod
|
| 634 |
+
def _get_config_file_from_dduf(cls, pretrained_model_name_or_path: str, dduf_entries: Dict[str, DDUFEntry]):
|
| 635 |
+
# paths inside a DDUF file must always be "/"
|
| 636 |
+
config_file = (
|
| 637 |
+
cls.config_name
|
| 638 |
+
if pretrained_model_name_or_path == ""
|
| 639 |
+
else "/".join([pretrained_model_name_or_path, cls.config_name])
|
| 640 |
+
)
|
| 641 |
+
if config_file not in dduf_entries:
|
| 642 |
+
raise ValueError(
|
| 643 |
+
f"We did not manage to find the file {config_file} in the dduf file. We only have the following files {dduf_entries.keys()}"
|
| 644 |
+
)
|
| 645 |
+
return config_file
|
| 646 |
+
|
| 647 |
+
|
| 648 |
+
def register_to_config(init):
|
| 649 |
+
r"""
|
| 650 |
+
Decorator to apply on the init of classes inheriting from [`ConfigMixin`] so that all the arguments are
|
| 651 |
+
automatically sent to `self.register_for_config`. To ignore a specific argument accepted by the init but that
|
| 652 |
+
shouldn't be registered in the config, use the `ignore_for_config` class variable
|
| 653 |
+
|
| 654 |
+
Warning: Once decorated, all private arguments (beginning with an underscore) are trashed and not sent to the init!
|
| 655 |
+
"""
|
| 656 |
+
|
| 657 |
+
@functools.wraps(init)
|
| 658 |
+
def inner_init(self, *args, **kwargs):
|
| 659 |
+
# Ignore private kwargs in the init.
|
| 660 |
+
init_kwargs = {k: v for k, v in kwargs.items() if not k.startswith("_")}
|
| 661 |
+
config_init_kwargs = {k: v for k, v in kwargs.items() if k.startswith("_")}
|
| 662 |
+
if not isinstance(self, ConfigMixin):
|
| 663 |
+
raise RuntimeError(
|
| 664 |
+
f"`@register_for_config` was applied to {self.__class__.__name__} init method, but this class does "
|
| 665 |
+
"not inherit from `ConfigMixin`."
|
| 666 |
+
)
|
| 667 |
+
|
| 668 |
+
ignore = getattr(self, "ignore_for_config", [])
|
| 669 |
+
# Get positional arguments aligned with kwargs
|
| 670 |
+
new_kwargs = {}
|
| 671 |
+
signature = inspect.signature(init)
|
| 672 |
+
parameters = {
|
| 673 |
+
name: p.default for i, (name, p) in enumerate(signature.parameters.items()) if i > 0 and name not in ignore
|
| 674 |
+
}
|
| 675 |
+
for arg, name in zip(args, parameters.keys()):
|
| 676 |
+
new_kwargs[name] = arg
|
| 677 |
+
|
| 678 |
+
# Then add all kwargs
|
| 679 |
+
new_kwargs.update(
|
| 680 |
+
{
|
| 681 |
+
k: init_kwargs.get(k, default)
|
| 682 |
+
for k, default in parameters.items()
|
| 683 |
+
if k not in ignore and k not in new_kwargs
|
| 684 |
+
}
|
| 685 |
+
)
|
| 686 |
+
|
| 687 |
+
# Take note of the parameters that were not present in the loaded config
|
| 688 |
+
if len(set(new_kwargs.keys()) - set(init_kwargs)) > 0:
|
| 689 |
+
new_kwargs["_use_default_values"] = list(set(new_kwargs.keys()) - set(init_kwargs))
|
| 690 |
+
|
| 691 |
+
new_kwargs = {**config_init_kwargs, **new_kwargs}
|
| 692 |
+
getattr(self, "register_to_config")(**new_kwargs)
|
| 693 |
+
init(self, *args, **init_kwargs)
|
| 694 |
+
|
| 695 |
+
return inner_init
|
| 696 |
+
|
| 697 |
+
|
| 698 |
+
def flax_register_to_config(cls):
|
| 699 |
+
original_init = cls.__init__
|
| 700 |
+
|
| 701 |
+
@functools.wraps(original_init)
|
| 702 |
+
def init(self, *args, **kwargs):
|
| 703 |
+
if not isinstance(self, ConfigMixin):
|
| 704 |
+
raise RuntimeError(
|
| 705 |
+
f"`@register_for_config` was applied to {self.__class__.__name__} init method, but this class does "
|
| 706 |
+
"not inherit from `ConfigMixin`."
|
| 707 |
+
)
|
| 708 |
+
|
| 709 |
+
# Ignore private kwargs in the init. Retrieve all passed attributes
|
| 710 |
+
init_kwargs = dict(kwargs.items())
|
| 711 |
+
|
| 712 |
+
# Retrieve default values
|
| 713 |
+
fields = dataclasses.fields(self)
|
| 714 |
+
default_kwargs = {}
|
| 715 |
+
for field in fields:
|
| 716 |
+
# ignore flax specific attributes
|
| 717 |
+
if field.name in self._flax_internal_args:
|
| 718 |
+
continue
|
| 719 |
+
if type(field.default) == dataclasses._MISSING_TYPE:
|
| 720 |
+
default_kwargs[field.name] = None
|
| 721 |
+
else:
|
| 722 |
+
default_kwargs[field.name] = getattr(self, field.name)
|
| 723 |
+
|
| 724 |
+
# Make sure init_kwargs override default kwargs
|
| 725 |
+
new_kwargs = {**default_kwargs, **init_kwargs}
|
| 726 |
+
# dtype should be part of `init_kwargs`, but not `new_kwargs`
|
| 727 |
+
if "dtype" in new_kwargs:
|
| 728 |
+
new_kwargs.pop("dtype")
|
| 729 |
+
|
| 730 |
+
# Get positional arguments aligned with kwargs
|
| 731 |
+
for i, arg in enumerate(args):
|
| 732 |
+
name = fields[i].name
|
| 733 |
+
new_kwargs[name] = arg
|
| 734 |
+
|
| 735 |
+
# Take note of the parameters that were not present in the loaded config
|
| 736 |
+
if len(set(new_kwargs.keys()) - set(init_kwargs)) > 0:
|
| 737 |
+
new_kwargs["_use_default_values"] = list(set(new_kwargs.keys()) - set(init_kwargs))
|
| 738 |
+
|
| 739 |
+
getattr(self, "register_to_config")(**new_kwargs)
|
| 740 |
+
original_init(self, *args, **kwargs)
|
| 741 |
+
|
| 742 |
+
cls.__init__ = init
|
| 743 |
+
return cls
|
| 744 |
+
|
| 745 |
+
|
| 746 |
+
class LegacyConfigMixin(ConfigMixin):
|
| 747 |
+
r"""
|
| 748 |
+
A subclass of `ConfigMixin` to resolve class mapping from legacy classes (like `Transformer2DModel`) to more
|
| 749 |
+
pipeline-specific classes (like `DiTTransformer2DModel`).
|
| 750 |
+
"""
|
| 751 |
+
|
| 752 |
+
@classmethod
|
| 753 |
+
def from_config(cls, config: Union[FrozenDict, Dict[str, Any]] = None, return_unused_kwargs=False, **kwargs):
|
| 754 |
+
# To prevent dependency import problem.
|
| 755 |
+
from .models.model_loading_utils import _fetch_remapped_cls_from_config
|
| 756 |
+
|
| 757 |
+
# resolve remapping
|
| 758 |
+
remapped_class = _fetch_remapped_cls_from_config(config, cls)
|
| 759 |
+
|
| 760 |
+
return remapped_class.from_config(config, return_unused_kwargs, **kwargs)
|
venv/lib/python3.10/site-packages/diffusers/dependency_versions_check.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
| 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 at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# 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 and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
from .dependency_versions_table import deps
|
| 16 |
+
from .utils.versions import require_version, require_version_core
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# define which module versions we always want to check at run time
|
| 20 |
+
# (usually the ones defined in `install_requires` in setup.py)
|
| 21 |
+
#
|
| 22 |
+
# order specific notes:
|
| 23 |
+
# - tqdm must be checked before tokenizers
|
| 24 |
+
|
| 25 |
+
pkgs_to_check_at_runtime = "python requests filelock numpy".split()
|
| 26 |
+
for pkg in pkgs_to_check_at_runtime:
|
| 27 |
+
if pkg in deps:
|
| 28 |
+
require_version_core(deps[pkg])
|
| 29 |
+
else:
|
| 30 |
+
raise ValueError(f"can't find {pkg} in {deps.keys()}, check dependency_versions_table.py")
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def dep_version_check(pkg, hint=None):
|
| 34 |
+
require_version(deps[pkg], hint)
|
venv/lib/python3.10/site-packages/diffusers/dependency_versions_table.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# THIS FILE HAS BEEN AUTOGENERATED. To update:
|
| 2 |
+
# 1. modify the `_deps` dict in setup.py
|
| 3 |
+
# 2. run `make deps_table_update`
|
| 4 |
+
deps = {
|
| 5 |
+
"Pillow": "Pillow",
|
| 6 |
+
"accelerate": "accelerate>=0.31.0",
|
| 7 |
+
"compel": "compel==0.1.8",
|
| 8 |
+
"datasets": "datasets",
|
| 9 |
+
"filelock": "filelock",
|
| 10 |
+
"flax": "flax>=0.4.1",
|
| 11 |
+
"hf-doc-builder": "hf-doc-builder>=0.3.0",
|
| 12 |
+
"huggingface-hub": "huggingface-hub>=0.27.0",
|
| 13 |
+
"requests-mock": "requests-mock==1.10.0",
|
| 14 |
+
"importlib_metadata": "importlib_metadata",
|
| 15 |
+
"invisible-watermark": "invisible-watermark>=0.2.0",
|
| 16 |
+
"isort": "isort>=5.5.4",
|
| 17 |
+
"jax": "jax>=0.4.1",
|
| 18 |
+
"jaxlib": "jaxlib>=0.4.1",
|
| 19 |
+
"Jinja2": "Jinja2",
|
| 20 |
+
"k-diffusion": "k-diffusion>=0.0.12",
|
| 21 |
+
"torchsde": "torchsde",
|
| 22 |
+
"note_seq": "note_seq",
|
| 23 |
+
"librosa": "librosa",
|
| 24 |
+
"numpy": "numpy",
|
| 25 |
+
"parameterized": "parameterized",
|
| 26 |
+
"peft": "peft>=0.15.0",
|
| 27 |
+
"protobuf": "protobuf>=3.20.3,<4",
|
| 28 |
+
"pytest": "pytest",
|
| 29 |
+
"pytest-timeout": "pytest-timeout",
|
| 30 |
+
"pytest-xdist": "pytest-xdist",
|
| 31 |
+
"python": "python>=3.8.0",
|
| 32 |
+
"ruff": "ruff==0.9.10",
|
| 33 |
+
"safetensors": "safetensors>=0.3.1",
|
| 34 |
+
"sentencepiece": "sentencepiece>=0.1.91,!=0.1.92",
|
| 35 |
+
"GitPython": "GitPython<3.1.19",
|
| 36 |
+
"scipy": "scipy",
|
| 37 |
+
"onnx": "onnx",
|
| 38 |
+
"optimum_quanto": "optimum_quanto>=0.2.6",
|
| 39 |
+
"gguf": "gguf>=0.10.0",
|
| 40 |
+
"torchao": "torchao>=0.7.0",
|
| 41 |
+
"bitsandbytes": "bitsandbytes>=0.43.3",
|
| 42 |
+
"regex": "regex!=2019.12.17",
|
| 43 |
+
"requests": "requests",
|
| 44 |
+
"tensorboard": "tensorboard",
|
| 45 |
+
"tiktoken": "tiktoken>=0.7.0",
|
| 46 |
+
"torch": "torch>=1.4",
|
| 47 |
+
"torchvision": "torchvision",
|
| 48 |
+
"transformers": "transformers>=4.41.2",
|
| 49 |
+
"urllib3": "urllib3<=2.0.0",
|
| 50 |
+
"black": "black",
|
| 51 |
+
"phonemizer": "phonemizer",
|
| 52 |
+
"opencv-python": "opencv-python",
|
| 53 |
+
}
|
venv/lib/python3.10/site-packages/diffusers/image_processor.py
ADDED
|
@@ -0,0 +1,1319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
| 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 at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# 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 and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import math
|
| 16 |
+
import warnings
|
| 17 |
+
from typing import List, Optional, Tuple, Union
|
| 18 |
+
|
| 19 |
+
import numpy as np
|
| 20 |
+
import PIL.Image
|
| 21 |
+
import torch
|
| 22 |
+
import torch.nn.functional as F
|
| 23 |
+
from PIL import Image, ImageFilter, ImageOps
|
| 24 |
+
|
| 25 |
+
from .configuration_utils import ConfigMixin, register_to_config
|
| 26 |
+
from .utils import CONFIG_NAME, PIL_INTERPOLATION, deprecate
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
PipelineImageInput = Union[
|
| 30 |
+
PIL.Image.Image,
|
| 31 |
+
np.ndarray,
|
| 32 |
+
torch.Tensor,
|
| 33 |
+
List[PIL.Image.Image],
|
| 34 |
+
List[np.ndarray],
|
| 35 |
+
List[torch.Tensor],
|
| 36 |
+
]
|
| 37 |
+
|
| 38 |
+
PipelineDepthInput = PipelineImageInput
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def is_valid_image(image) -> bool:
|
| 42 |
+
r"""
|
| 43 |
+
Checks if the input is a valid image.
|
| 44 |
+
|
| 45 |
+
A valid image can be:
|
| 46 |
+
- A `PIL.Image.Image`.
|
| 47 |
+
- A 2D or 3D `np.ndarray` or `torch.Tensor` (grayscale or color image).
|
| 48 |
+
|
| 49 |
+
Args:
|
| 50 |
+
image (`Union[PIL.Image.Image, np.ndarray, torch.Tensor]`):
|
| 51 |
+
The image to validate. It can be a PIL image, a NumPy array, or a torch tensor.
|
| 52 |
+
|
| 53 |
+
Returns:
|
| 54 |
+
`bool`:
|
| 55 |
+
`True` if the input is a valid image, `False` otherwise.
|
| 56 |
+
"""
|
| 57 |
+
return isinstance(image, PIL.Image.Image) or isinstance(image, (np.ndarray, torch.Tensor)) and image.ndim in (2, 3)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def is_valid_image_imagelist(images):
|
| 61 |
+
r"""
|
| 62 |
+
Checks if the input is a valid image or list of images.
|
| 63 |
+
|
| 64 |
+
The input can be one of the following formats:
|
| 65 |
+
- A 4D tensor or numpy array (batch of images).
|
| 66 |
+
- A valid single image: `PIL.Image.Image`, 2D `np.ndarray` or `torch.Tensor` (grayscale image), 3D `np.ndarray` or
|
| 67 |
+
`torch.Tensor`.
|
| 68 |
+
- A list of valid images.
|
| 69 |
+
|
| 70 |
+
Args:
|
| 71 |
+
images (`Union[np.ndarray, torch.Tensor, PIL.Image.Image, List]`):
|
| 72 |
+
The image(s) to check. Can be a batch of images (4D tensor/array), a single image, or a list of valid
|
| 73 |
+
images.
|
| 74 |
+
|
| 75 |
+
Returns:
|
| 76 |
+
`bool`:
|
| 77 |
+
`True` if the input is valid, `False` otherwise.
|
| 78 |
+
"""
|
| 79 |
+
if isinstance(images, (np.ndarray, torch.Tensor)) and images.ndim == 4:
|
| 80 |
+
return True
|
| 81 |
+
elif is_valid_image(images):
|
| 82 |
+
return True
|
| 83 |
+
elif isinstance(images, list):
|
| 84 |
+
return all(is_valid_image(image) for image in images)
|
| 85 |
+
return False
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
class VaeImageProcessor(ConfigMixin):
|
| 89 |
+
"""
|
| 90 |
+
Image processor for VAE.
|
| 91 |
+
|
| 92 |
+
Args:
|
| 93 |
+
do_resize (`bool`, *optional*, defaults to `True`):
|
| 94 |
+
Whether to downscale the image's (height, width) dimensions to multiples of `vae_scale_factor`. Can accept
|
| 95 |
+
`height` and `width` arguments from [`image_processor.VaeImageProcessor.preprocess`] method.
|
| 96 |
+
vae_scale_factor (`int`, *optional*, defaults to `8`):
|
| 97 |
+
VAE scale factor. If `do_resize` is `True`, the image is automatically resized to multiples of this factor.
|
| 98 |
+
resample (`str`, *optional*, defaults to `lanczos`):
|
| 99 |
+
Resampling filter to use when resizing the image.
|
| 100 |
+
do_normalize (`bool`, *optional*, defaults to `True`):
|
| 101 |
+
Whether to normalize the image to [-1,1].
|
| 102 |
+
do_binarize (`bool`, *optional*, defaults to `False`):
|
| 103 |
+
Whether to binarize the image to 0/1.
|
| 104 |
+
do_convert_rgb (`bool`, *optional*, defaults to be `False`):
|
| 105 |
+
Whether to convert the images to RGB format.
|
| 106 |
+
do_convert_grayscale (`bool`, *optional*, defaults to be `False`):
|
| 107 |
+
Whether to convert the images to grayscale format.
|
| 108 |
+
"""
|
| 109 |
+
|
| 110 |
+
config_name = CONFIG_NAME
|
| 111 |
+
|
| 112 |
+
@register_to_config
|
| 113 |
+
def __init__(
|
| 114 |
+
self,
|
| 115 |
+
do_resize: bool = True,
|
| 116 |
+
vae_scale_factor: int = 8,
|
| 117 |
+
vae_latent_channels: int = 4,
|
| 118 |
+
resample: str = "lanczos",
|
| 119 |
+
reducing_gap: int = None,
|
| 120 |
+
do_normalize: bool = True,
|
| 121 |
+
do_binarize: bool = False,
|
| 122 |
+
do_convert_rgb: bool = False,
|
| 123 |
+
do_convert_grayscale: bool = False,
|
| 124 |
+
):
|
| 125 |
+
super().__init__()
|
| 126 |
+
if do_convert_rgb and do_convert_grayscale:
|
| 127 |
+
raise ValueError(
|
| 128 |
+
"`do_convert_rgb` and `do_convert_grayscale` can not both be set to `True`,"
|
| 129 |
+
" if you intended to convert the image into RGB format, please set `do_convert_grayscale = False`.",
|
| 130 |
+
" if you intended to convert the image into grayscale format, please set `do_convert_rgb = False`",
|
| 131 |
+
)
|
| 132 |
+
|
| 133 |
+
@staticmethod
|
| 134 |
+
def numpy_to_pil(images: np.ndarray) -> List[PIL.Image.Image]:
|
| 135 |
+
r"""
|
| 136 |
+
Convert a numpy image or a batch of images to a PIL image.
|
| 137 |
+
|
| 138 |
+
Args:
|
| 139 |
+
images (`np.ndarray`):
|
| 140 |
+
The image array to convert to PIL format.
|
| 141 |
+
|
| 142 |
+
Returns:
|
| 143 |
+
`List[PIL.Image.Image]`:
|
| 144 |
+
A list of PIL images.
|
| 145 |
+
"""
|
| 146 |
+
if images.ndim == 3:
|
| 147 |
+
images = images[None, ...]
|
| 148 |
+
images = (images * 255).round().astype("uint8")
|
| 149 |
+
if images.shape[-1] == 1:
|
| 150 |
+
# special case for grayscale (single channel) images
|
| 151 |
+
pil_images = [Image.fromarray(image.squeeze(), mode="L") for image in images]
|
| 152 |
+
else:
|
| 153 |
+
pil_images = [Image.fromarray(image) for image in images]
|
| 154 |
+
|
| 155 |
+
return pil_images
|
| 156 |
+
|
| 157 |
+
@staticmethod
|
| 158 |
+
def pil_to_numpy(images: Union[List[PIL.Image.Image], PIL.Image.Image]) -> np.ndarray:
|
| 159 |
+
r"""
|
| 160 |
+
Convert a PIL image or a list of PIL images to NumPy arrays.
|
| 161 |
+
|
| 162 |
+
Args:
|
| 163 |
+
images (`PIL.Image.Image` or `List[PIL.Image.Image]`):
|
| 164 |
+
The PIL image or list of images to convert to NumPy format.
|
| 165 |
+
|
| 166 |
+
Returns:
|
| 167 |
+
`np.ndarray`:
|
| 168 |
+
A NumPy array representation of the images.
|
| 169 |
+
"""
|
| 170 |
+
if not isinstance(images, list):
|
| 171 |
+
images = [images]
|
| 172 |
+
images = [np.array(image).astype(np.float32) / 255.0 for image in images]
|
| 173 |
+
images = np.stack(images, axis=0)
|
| 174 |
+
|
| 175 |
+
return images
|
| 176 |
+
|
| 177 |
+
@staticmethod
|
| 178 |
+
def numpy_to_pt(images: np.ndarray) -> torch.Tensor:
|
| 179 |
+
r"""
|
| 180 |
+
Convert a NumPy image to a PyTorch tensor.
|
| 181 |
+
|
| 182 |
+
Args:
|
| 183 |
+
images (`np.ndarray`):
|
| 184 |
+
The NumPy image array to convert to PyTorch format.
|
| 185 |
+
|
| 186 |
+
Returns:
|
| 187 |
+
`torch.Tensor`:
|
| 188 |
+
A PyTorch tensor representation of the images.
|
| 189 |
+
"""
|
| 190 |
+
if images.ndim == 3:
|
| 191 |
+
images = images[..., None]
|
| 192 |
+
|
| 193 |
+
images = torch.from_numpy(images.transpose(0, 3, 1, 2))
|
| 194 |
+
return images
|
| 195 |
+
|
| 196 |
+
@staticmethod
|
| 197 |
+
def pt_to_numpy(images: torch.Tensor) -> np.ndarray:
|
| 198 |
+
r"""
|
| 199 |
+
Convert a PyTorch tensor to a NumPy image.
|
| 200 |
+
|
| 201 |
+
Args:
|
| 202 |
+
images (`torch.Tensor`):
|
| 203 |
+
The PyTorch tensor to convert to NumPy format.
|
| 204 |
+
|
| 205 |
+
Returns:
|
| 206 |
+
`np.ndarray`:
|
| 207 |
+
A NumPy array representation of the images.
|
| 208 |
+
"""
|
| 209 |
+
images = images.cpu().permute(0, 2, 3, 1).float().numpy()
|
| 210 |
+
return images
|
| 211 |
+
|
| 212 |
+
@staticmethod
|
| 213 |
+
def normalize(images: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]:
|
| 214 |
+
r"""
|
| 215 |
+
Normalize an image array to [-1,1].
|
| 216 |
+
|
| 217 |
+
Args:
|
| 218 |
+
images (`np.ndarray` or `torch.Tensor`):
|
| 219 |
+
The image array to normalize.
|
| 220 |
+
|
| 221 |
+
Returns:
|
| 222 |
+
`np.ndarray` or `torch.Tensor`:
|
| 223 |
+
The normalized image array.
|
| 224 |
+
"""
|
| 225 |
+
return 2.0 * images - 1.0
|
| 226 |
+
|
| 227 |
+
@staticmethod
|
| 228 |
+
def denormalize(images: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]:
|
| 229 |
+
r"""
|
| 230 |
+
Denormalize an image array to [0,1].
|
| 231 |
+
|
| 232 |
+
Args:
|
| 233 |
+
images (`np.ndarray` or `torch.Tensor`):
|
| 234 |
+
The image array to denormalize.
|
| 235 |
+
|
| 236 |
+
Returns:
|
| 237 |
+
`np.ndarray` or `torch.Tensor`:
|
| 238 |
+
The denormalized image array.
|
| 239 |
+
"""
|
| 240 |
+
return (images * 0.5 + 0.5).clamp(0, 1)
|
| 241 |
+
|
| 242 |
+
@staticmethod
|
| 243 |
+
def convert_to_rgb(image: PIL.Image.Image) -> PIL.Image.Image:
|
| 244 |
+
r"""
|
| 245 |
+
Converts a PIL image to RGB format.
|
| 246 |
+
|
| 247 |
+
Args:
|
| 248 |
+
image (`PIL.Image.Image`):
|
| 249 |
+
The PIL image to convert to RGB.
|
| 250 |
+
|
| 251 |
+
Returns:
|
| 252 |
+
`PIL.Image.Image`:
|
| 253 |
+
The RGB-converted PIL image.
|
| 254 |
+
"""
|
| 255 |
+
image = image.convert("RGB")
|
| 256 |
+
|
| 257 |
+
return image
|
| 258 |
+
|
| 259 |
+
@staticmethod
|
| 260 |
+
def convert_to_grayscale(image: PIL.Image.Image) -> PIL.Image.Image:
|
| 261 |
+
r"""
|
| 262 |
+
Converts a given PIL image to grayscale.
|
| 263 |
+
|
| 264 |
+
Args:
|
| 265 |
+
image (`PIL.Image.Image`):
|
| 266 |
+
The input image to convert.
|
| 267 |
+
|
| 268 |
+
Returns:
|
| 269 |
+
`PIL.Image.Image`:
|
| 270 |
+
The image converted to grayscale.
|
| 271 |
+
"""
|
| 272 |
+
image = image.convert("L")
|
| 273 |
+
|
| 274 |
+
return image
|
| 275 |
+
|
| 276 |
+
@staticmethod
|
| 277 |
+
def blur(image: PIL.Image.Image, blur_factor: int = 4) -> PIL.Image.Image:
|
| 278 |
+
r"""
|
| 279 |
+
Applies Gaussian blur to an image.
|
| 280 |
+
|
| 281 |
+
Args:
|
| 282 |
+
image (`PIL.Image.Image`):
|
| 283 |
+
The PIL image to convert to grayscale.
|
| 284 |
+
|
| 285 |
+
Returns:
|
| 286 |
+
`PIL.Image.Image`:
|
| 287 |
+
The grayscale-converted PIL image.
|
| 288 |
+
"""
|
| 289 |
+
image = image.filter(ImageFilter.GaussianBlur(blur_factor))
|
| 290 |
+
|
| 291 |
+
return image
|
| 292 |
+
|
| 293 |
+
@staticmethod
|
| 294 |
+
def get_crop_region(mask_image: PIL.Image.Image, width: int, height: int, pad=0):
|
| 295 |
+
r"""
|
| 296 |
+
Finds a rectangular region that contains all masked ares in an image, and expands region to match the aspect
|
| 297 |
+
ratio of the original image; for example, if user drew mask in a 128x32 region, and the dimensions for
|
| 298 |
+
processing are 512x512, the region will be expanded to 128x128.
|
| 299 |
+
|
| 300 |
+
Args:
|
| 301 |
+
mask_image (PIL.Image.Image): Mask image.
|
| 302 |
+
width (int): Width of the image to be processed.
|
| 303 |
+
height (int): Height of the image to be processed.
|
| 304 |
+
pad (int, optional): Padding to be added to the crop region. Defaults to 0.
|
| 305 |
+
|
| 306 |
+
Returns:
|
| 307 |
+
tuple: (x1, y1, x2, y2) represent a rectangular region that contains all masked ares in an image and
|
| 308 |
+
matches the original aspect ratio.
|
| 309 |
+
"""
|
| 310 |
+
|
| 311 |
+
mask_image = mask_image.convert("L")
|
| 312 |
+
mask = np.array(mask_image)
|
| 313 |
+
|
| 314 |
+
# 1. find a rectangular region that contains all masked ares in an image
|
| 315 |
+
h, w = mask.shape
|
| 316 |
+
crop_left = 0
|
| 317 |
+
for i in range(w):
|
| 318 |
+
if not (mask[:, i] == 0).all():
|
| 319 |
+
break
|
| 320 |
+
crop_left += 1
|
| 321 |
+
|
| 322 |
+
crop_right = 0
|
| 323 |
+
for i in reversed(range(w)):
|
| 324 |
+
if not (mask[:, i] == 0).all():
|
| 325 |
+
break
|
| 326 |
+
crop_right += 1
|
| 327 |
+
|
| 328 |
+
crop_top = 0
|
| 329 |
+
for i in range(h):
|
| 330 |
+
if not (mask[i] == 0).all():
|
| 331 |
+
break
|
| 332 |
+
crop_top += 1
|
| 333 |
+
|
| 334 |
+
crop_bottom = 0
|
| 335 |
+
for i in reversed(range(h)):
|
| 336 |
+
if not (mask[i] == 0).all():
|
| 337 |
+
break
|
| 338 |
+
crop_bottom += 1
|
| 339 |
+
|
| 340 |
+
# 2. add padding to the crop region
|
| 341 |
+
x1, y1, x2, y2 = (
|
| 342 |
+
int(max(crop_left - pad, 0)),
|
| 343 |
+
int(max(crop_top - pad, 0)),
|
| 344 |
+
int(min(w - crop_right + pad, w)),
|
| 345 |
+
int(min(h - crop_bottom + pad, h)),
|
| 346 |
+
)
|
| 347 |
+
|
| 348 |
+
# 3. expands crop region to match the aspect ratio of the image to be processed
|
| 349 |
+
ratio_crop_region = (x2 - x1) / (y2 - y1)
|
| 350 |
+
ratio_processing = width / height
|
| 351 |
+
|
| 352 |
+
if ratio_crop_region > ratio_processing:
|
| 353 |
+
desired_height = (x2 - x1) / ratio_processing
|
| 354 |
+
desired_height_diff = int(desired_height - (y2 - y1))
|
| 355 |
+
y1 -= desired_height_diff // 2
|
| 356 |
+
y2 += desired_height_diff - desired_height_diff // 2
|
| 357 |
+
if y2 >= mask_image.height:
|
| 358 |
+
diff = y2 - mask_image.height
|
| 359 |
+
y2 -= diff
|
| 360 |
+
y1 -= diff
|
| 361 |
+
if y1 < 0:
|
| 362 |
+
y2 -= y1
|
| 363 |
+
y1 -= y1
|
| 364 |
+
if y2 >= mask_image.height:
|
| 365 |
+
y2 = mask_image.height
|
| 366 |
+
else:
|
| 367 |
+
desired_width = (y2 - y1) * ratio_processing
|
| 368 |
+
desired_width_diff = int(desired_width - (x2 - x1))
|
| 369 |
+
x1 -= desired_width_diff // 2
|
| 370 |
+
x2 += desired_width_diff - desired_width_diff // 2
|
| 371 |
+
if x2 >= mask_image.width:
|
| 372 |
+
diff = x2 - mask_image.width
|
| 373 |
+
x2 -= diff
|
| 374 |
+
x1 -= diff
|
| 375 |
+
if x1 < 0:
|
| 376 |
+
x2 -= x1
|
| 377 |
+
x1 -= x1
|
| 378 |
+
if x2 >= mask_image.width:
|
| 379 |
+
x2 = mask_image.width
|
| 380 |
+
|
| 381 |
+
return x1, y1, x2, y2
|
| 382 |
+
|
| 383 |
+
def _resize_and_fill(
|
| 384 |
+
self,
|
| 385 |
+
image: PIL.Image.Image,
|
| 386 |
+
width: int,
|
| 387 |
+
height: int,
|
| 388 |
+
) -> PIL.Image.Image:
|
| 389 |
+
r"""
|
| 390 |
+
Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center
|
| 391 |
+
the image within the dimensions, filling empty with data from image.
|
| 392 |
+
|
| 393 |
+
Args:
|
| 394 |
+
image (`PIL.Image.Image`):
|
| 395 |
+
The image to resize and fill.
|
| 396 |
+
width (`int`):
|
| 397 |
+
The width to resize the image to.
|
| 398 |
+
height (`int`):
|
| 399 |
+
The height to resize the image to.
|
| 400 |
+
|
| 401 |
+
Returns:
|
| 402 |
+
`PIL.Image.Image`:
|
| 403 |
+
The resized and filled image.
|
| 404 |
+
"""
|
| 405 |
+
|
| 406 |
+
ratio = width / height
|
| 407 |
+
src_ratio = image.width / image.height
|
| 408 |
+
|
| 409 |
+
src_w = width if ratio < src_ratio else image.width * height // image.height
|
| 410 |
+
src_h = height if ratio >= src_ratio else image.height * width // image.width
|
| 411 |
+
|
| 412 |
+
resized = image.resize((src_w, src_h), resample=PIL_INTERPOLATION["lanczos"])
|
| 413 |
+
res = Image.new("RGB", (width, height))
|
| 414 |
+
res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2))
|
| 415 |
+
|
| 416 |
+
if ratio < src_ratio:
|
| 417 |
+
fill_height = height // 2 - src_h // 2
|
| 418 |
+
if fill_height > 0:
|
| 419 |
+
res.paste(resized.resize((width, fill_height), box=(0, 0, width, 0)), box=(0, 0))
|
| 420 |
+
res.paste(
|
| 421 |
+
resized.resize((width, fill_height), box=(0, resized.height, width, resized.height)),
|
| 422 |
+
box=(0, fill_height + src_h),
|
| 423 |
+
)
|
| 424 |
+
elif ratio > src_ratio:
|
| 425 |
+
fill_width = width // 2 - src_w // 2
|
| 426 |
+
if fill_width > 0:
|
| 427 |
+
res.paste(resized.resize((fill_width, height), box=(0, 0, 0, height)), box=(0, 0))
|
| 428 |
+
res.paste(
|
| 429 |
+
resized.resize((fill_width, height), box=(resized.width, 0, resized.width, height)),
|
| 430 |
+
box=(fill_width + src_w, 0),
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
+
return res
|
| 434 |
+
|
| 435 |
+
def _resize_and_crop(
|
| 436 |
+
self,
|
| 437 |
+
image: PIL.Image.Image,
|
| 438 |
+
width: int,
|
| 439 |
+
height: int,
|
| 440 |
+
) -> PIL.Image.Image:
|
| 441 |
+
r"""
|
| 442 |
+
Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center
|
| 443 |
+
the image within the dimensions, cropping the excess.
|
| 444 |
+
|
| 445 |
+
Args:
|
| 446 |
+
image (`PIL.Image.Image`):
|
| 447 |
+
The image to resize and crop.
|
| 448 |
+
width (`int`):
|
| 449 |
+
The width to resize the image to.
|
| 450 |
+
height (`int`):
|
| 451 |
+
The height to resize the image to.
|
| 452 |
+
|
| 453 |
+
Returns:
|
| 454 |
+
`PIL.Image.Image`:
|
| 455 |
+
The resized and cropped image.
|
| 456 |
+
"""
|
| 457 |
+
ratio = width / height
|
| 458 |
+
src_ratio = image.width / image.height
|
| 459 |
+
|
| 460 |
+
src_w = width if ratio > src_ratio else image.width * height // image.height
|
| 461 |
+
src_h = height if ratio <= src_ratio else image.height * width // image.width
|
| 462 |
+
|
| 463 |
+
resized = image.resize((src_w, src_h), resample=PIL_INTERPOLATION["lanczos"])
|
| 464 |
+
res = Image.new("RGB", (width, height))
|
| 465 |
+
res.paste(resized, box=(width // 2 - src_w // 2, height // 2 - src_h // 2))
|
| 466 |
+
return res
|
| 467 |
+
|
| 468 |
+
def resize(
|
| 469 |
+
self,
|
| 470 |
+
image: Union[PIL.Image.Image, np.ndarray, torch.Tensor],
|
| 471 |
+
height: int,
|
| 472 |
+
width: int,
|
| 473 |
+
resize_mode: str = "default", # "default", "fill", "crop"
|
| 474 |
+
) -> Union[PIL.Image.Image, np.ndarray, torch.Tensor]:
|
| 475 |
+
"""
|
| 476 |
+
Resize image.
|
| 477 |
+
|
| 478 |
+
Args:
|
| 479 |
+
image (`PIL.Image.Image`, `np.ndarray` or `torch.Tensor`):
|
| 480 |
+
The image input, can be a PIL image, numpy array or pytorch tensor.
|
| 481 |
+
height (`int`):
|
| 482 |
+
The height to resize to.
|
| 483 |
+
width (`int`):
|
| 484 |
+
The width to resize to.
|
| 485 |
+
resize_mode (`str`, *optional*, defaults to `default`):
|
| 486 |
+
The resize mode to use, can be one of `default` or `fill`. If `default`, will resize the image to fit
|
| 487 |
+
within the specified width and height, and it may not maintaining the original aspect ratio. If `fill`,
|
| 488 |
+
will resize the image to fit within the specified width and height, maintaining the aspect ratio, and
|
| 489 |
+
then center the image within the dimensions, filling empty with data from image. If `crop`, will resize
|
| 490 |
+
the image to fit within the specified width and height, maintaining the aspect ratio, and then center
|
| 491 |
+
the image within the dimensions, cropping the excess. Note that resize_mode `fill` and `crop` are only
|
| 492 |
+
supported for PIL image input.
|
| 493 |
+
|
| 494 |
+
Returns:
|
| 495 |
+
`PIL.Image.Image`, `np.ndarray` or `torch.Tensor`:
|
| 496 |
+
The resized image.
|
| 497 |
+
"""
|
| 498 |
+
if resize_mode != "default" and not isinstance(image, PIL.Image.Image):
|
| 499 |
+
raise ValueError(f"Only PIL image input is supported for resize_mode {resize_mode}")
|
| 500 |
+
if isinstance(image, PIL.Image.Image):
|
| 501 |
+
if resize_mode == "default":
|
| 502 |
+
image = image.resize(
|
| 503 |
+
(width, height),
|
| 504 |
+
resample=PIL_INTERPOLATION[self.config.resample],
|
| 505 |
+
reducing_gap=self.config.reducing_gap,
|
| 506 |
+
)
|
| 507 |
+
elif resize_mode == "fill":
|
| 508 |
+
image = self._resize_and_fill(image, width, height)
|
| 509 |
+
elif resize_mode == "crop":
|
| 510 |
+
image = self._resize_and_crop(image, width, height)
|
| 511 |
+
else:
|
| 512 |
+
raise ValueError(f"resize_mode {resize_mode} is not supported")
|
| 513 |
+
|
| 514 |
+
elif isinstance(image, torch.Tensor):
|
| 515 |
+
image = torch.nn.functional.interpolate(
|
| 516 |
+
image,
|
| 517 |
+
size=(height, width),
|
| 518 |
+
)
|
| 519 |
+
elif isinstance(image, np.ndarray):
|
| 520 |
+
image = self.numpy_to_pt(image)
|
| 521 |
+
image = torch.nn.functional.interpolate(
|
| 522 |
+
image,
|
| 523 |
+
size=(height, width),
|
| 524 |
+
)
|
| 525 |
+
image = self.pt_to_numpy(image)
|
| 526 |
+
return image
|
| 527 |
+
|
| 528 |
+
def binarize(self, image: PIL.Image.Image) -> PIL.Image.Image:
|
| 529 |
+
"""
|
| 530 |
+
Create a mask.
|
| 531 |
+
|
| 532 |
+
Args:
|
| 533 |
+
image (`PIL.Image.Image`):
|
| 534 |
+
The image input, should be a PIL image.
|
| 535 |
+
|
| 536 |
+
Returns:
|
| 537 |
+
`PIL.Image.Image`:
|
| 538 |
+
The binarized image. Values less than 0.5 are set to 0, values greater than 0.5 are set to 1.
|
| 539 |
+
"""
|
| 540 |
+
image[image < 0.5] = 0
|
| 541 |
+
image[image >= 0.5] = 1
|
| 542 |
+
|
| 543 |
+
return image
|
| 544 |
+
|
| 545 |
+
def _denormalize_conditionally(
|
| 546 |
+
self, images: torch.Tensor, do_denormalize: Optional[List[bool]] = None
|
| 547 |
+
) -> torch.Tensor:
|
| 548 |
+
r"""
|
| 549 |
+
Denormalize a batch of images based on a condition list.
|
| 550 |
+
|
| 551 |
+
Args:
|
| 552 |
+
images (`torch.Tensor`):
|
| 553 |
+
The input image tensor.
|
| 554 |
+
do_denormalize (`Optional[List[bool]`, *optional*, defaults to `None`):
|
| 555 |
+
A list of booleans indicating whether to denormalize each image in the batch. If `None`, will use the
|
| 556 |
+
value of `do_normalize` in the `VaeImageProcessor` config.
|
| 557 |
+
"""
|
| 558 |
+
if do_denormalize is None:
|
| 559 |
+
return self.denormalize(images) if self.config.do_normalize else images
|
| 560 |
+
|
| 561 |
+
return torch.stack(
|
| 562 |
+
[self.denormalize(images[i]) if do_denormalize[i] else images[i] for i in range(images.shape[0])]
|
| 563 |
+
)
|
| 564 |
+
|
| 565 |
+
def get_default_height_width(
|
| 566 |
+
self,
|
| 567 |
+
image: Union[PIL.Image.Image, np.ndarray, torch.Tensor],
|
| 568 |
+
height: Optional[int] = None,
|
| 569 |
+
width: Optional[int] = None,
|
| 570 |
+
) -> Tuple[int, int]:
|
| 571 |
+
r"""
|
| 572 |
+
Returns the height and width of the image, downscaled to the next integer multiple of `vae_scale_factor`.
|
| 573 |
+
|
| 574 |
+
Args:
|
| 575 |
+
image (`Union[PIL.Image.Image, np.ndarray, torch.Tensor]`):
|
| 576 |
+
The image input, which can be a PIL image, NumPy array, or PyTorch tensor. If it is a NumPy array, it
|
| 577 |
+
should have shape `[batch, height, width]` or `[batch, height, width, channels]`. If it is a PyTorch
|
| 578 |
+
tensor, it should have shape `[batch, channels, height, width]`.
|
| 579 |
+
height (`Optional[int]`, *optional*, defaults to `None`):
|
| 580 |
+
The height of the preprocessed image. If `None`, the height of the `image` input will be used.
|
| 581 |
+
width (`Optional[int]`, *optional*, defaults to `None`):
|
| 582 |
+
The width of the preprocessed image. If `None`, the width of the `image` input will be used.
|
| 583 |
+
|
| 584 |
+
Returns:
|
| 585 |
+
`Tuple[int, int]`:
|
| 586 |
+
A tuple containing the height and width, both resized to the nearest integer multiple of
|
| 587 |
+
`vae_scale_factor`.
|
| 588 |
+
"""
|
| 589 |
+
|
| 590 |
+
if height is None:
|
| 591 |
+
if isinstance(image, PIL.Image.Image):
|
| 592 |
+
height = image.height
|
| 593 |
+
elif isinstance(image, torch.Tensor):
|
| 594 |
+
height = image.shape[2]
|
| 595 |
+
else:
|
| 596 |
+
height = image.shape[1]
|
| 597 |
+
|
| 598 |
+
if width is None:
|
| 599 |
+
if isinstance(image, PIL.Image.Image):
|
| 600 |
+
width = image.width
|
| 601 |
+
elif isinstance(image, torch.Tensor):
|
| 602 |
+
width = image.shape[3]
|
| 603 |
+
else:
|
| 604 |
+
width = image.shape[2]
|
| 605 |
+
|
| 606 |
+
width, height = (
|
| 607 |
+
x - x % self.config.vae_scale_factor for x in (width, height)
|
| 608 |
+
) # resize to integer multiple of vae_scale_factor
|
| 609 |
+
|
| 610 |
+
return height, width
|
| 611 |
+
|
| 612 |
+
def preprocess(
|
| 613 |
+
self,
|
| 614 |
+
image: PipelineImageInput,
|
| 615 |
+
height: Optional[int] = None,
|
| 616 |
+
width: Optional[int] = None,
|
| 617 |
+
resize_mode: str = "default", # "default", "fill", "crop"
|
| 618 |
+
crops_coords: Optional[Tuple[int, int, int, int]] = None,
|
| 619 |
+
) -> torch.Tensor:
|
| 620 |
+
"""
|
| 621 |
+
Preprocess the image input.
|
| 622 |
+
|
| 623 |
+
Args:
|
| 624 |
+
image (`PipelineImageInput`):
|
| 625 |
+
The image input, accepted formats are PIL images, NumPy arrays, PyTorch tensors; Also accept list of
|
| 626 |
+
supported formats.
|
| 627 |
+
height (`int`, *optional*):
|
| 628 |
+
The height in preprocessed image. If `None`, will use the `get_default_height_width()` to get default
|
| 629 |
+
height.
|
| 630 |
+
width (`int`, *optional*):
|
| 631 |
+
The width in preprocessed. If `None`, will use get_default_height_width()` to get the default width.
|
| 632 |
+
resize_mode (`str`, *optional*, defaults to `default`):
|
| 633 |
+
The resize mode, can be one of `default` or `fill`. If `default`, will resize the image to fit within
|
| 634 |
+
the specified width and height, and it may not maintaining the original aspect ratio. If `fill`, will
|
| 635 |
+
resize the image to fit within the specified width and height, maintaining the aspect ratio, and then
|
| 636 |
+
center the image within the dimensions, filling empty with data from image. If `crop`, will resize the
|
| 637 |
+
image to fit within the specified width and height, maintaining the aspect ratio, and then center the
|
| 638 |
+
image within the dimensions, cropping the excess. Note that resize_mode `fill` and `crop` are only
|
| 639 |
+
supported for PIL image input.
|
| 640 |
+
crops_coords (`List[Tuple[int, int, int, int]]`, *optional*, defaults to `None`):
|
| 641 |
+
The crop coordinates for each image in the batch. If `None`, will not crop the image.
|
| 642 |
+
|
| 643 |
+
Returns:
|
| 644 |
+
`torch.Tensor`:
|
| 645 |
+
The preprocessed image.
|
| 646 |
+
"""
|
| 647 |
+
supported_formats = (PIL.Image.Image, np.ndarray, torch.Tensor)
|
| 648 |
+
|
| 649 |
+
# Expand the missing dimension for 3-dimensional pytorch tensor or numpy array that represents grayscale image
|
| 650 |
+
if self.config.do_convert_grayscale and isinstance(image, (torch.Tensor, np.ndarray)) and image.ndim == 3:
|
| 651 |
+
if isinstance(image, torch.Tensor):
|
| 652 |
+
# if image is a pytorch tensor could have 2 possible shapes:
|
| 653 |
+
# 1. batch x height x width: we should insert the channel dimension at position 1
|
| 654 |
+
# 2. channel x height x width: we should insert batch dimension at position 0,
|
| 655 |
+
# however, since both channel and batch dimension has same size 1, it is same to insert at position 1
|
| 656 |
+
# for simplicity, we insert a dimension of size 1 at position 1 for both cases
|
| 657 |
+
image = image.unsqueeze(1)
|
| 658 |
+
else:
|
| 659 |
+
# if it is a numpy array, it could have 2 possible shapes:
|
| 660 |
+
# 1. batch x height x width: insert channel dimension on last position
|
| 661 |
+
# 2. height x width x channel: insert batch dimension on first position
|
| 662 |
+
if image.shape[-1] == 1:
|
| 663 |
+
image = np.expand_dims(image, axis=0)
|
| 664 |
+
else:
|
| 665 |
+
image = np.expand_dims(image, axis=-1)
|
| 666 |
+
|
| 667 |
+
if isinstance(image, list) and isinstance(image[0], np.ndarray) and image[0].ndim == 4:
|
| 668 |
+
warnings.warn(
|
| 669 |
+
"Passing `image` as a list of 4d np.ndarray is deprecated."
|
| 670 |
+
"Please concatenate the list along the batch dimension and pass it as a single 4d np.ndarray",
|
| 671 |
+
FutureWarning,
|
| 672 |
+
)
|
| 673 |
+
image = np.concatenate(image, axis=0)
|
| 674 |
+
if isinstance(image, list) and isinstance(image[0], torch.Tensor) and image[0].ndim == 4:
|
| 675 |
+
warnings.warn(
|
| 676 |
+
"Passing `image` as a list of 4d torch.Tensor is deprecated."
|
| 677 |
+
"Please concatenate the list along the batch dimension and pass it as a single 4d torch.Tensor",
|
| 678 |
+
FutureWarning,
|
| 679 |
+
)
|
| 680 |
+
image = torch.cat(image, axis=0)
|
| 681 |
+
|
| 682 |
+
if not is_valid_image_imagelist(image):
|
| 683 |
+
raise ValueError(
|
| 684 |
+
f"Input is in incorrect format. Currently, we only support {', '.join(str(x) for x in supported_formats)}"
|
| 685 |
+
)
|
| 686 |
+
if not isinstance(image, list):
|
| 687 |
+
image = [image]
|
| 688 |
+
|
| 689 |
+
if isinstance(image[0], PIL.Image.Image):
|
| 690 |
+
if crops_coords is not None:
|
| 691 |
+
image = [i.crop(crops_coords) for i in image]
|
| 692 |
+
if self.config.do_resize:
|
| 693 |
+
height, width = self.get_default_height_width(image[0], height, width)
|
| 694 |
+
image = [self.resize(i, height, width, resize_mode=resize_mode) for i in image]
|
| 695 |
+
if self.config.do_convert_rgb:
|
| 696 |
+
image = [self.convert_to_rgb(i) for i in image]
|
| 697 |
+
elif self.config.do_convert_grayscale:
|
| 698 |
+
image = [self.convert_to_grayscale(i) for i in image]
|
| 699 |
+
image = self.pil_to_numpy(image) # to np
|
| 700 |
+
image = self.numpy_to_pt(image) # to pt
|
| 701 |
+
|
| 702 |
+
elif isinstance(image[0], np.ndarray):
|
| 703 |
+
image = np.concatenate(image, axis=0) if image[0].ndim == 4 else np.stack(image, axis=0)
|
| 704 |
+
|
| 705 |
+
image = self.numpy_to_pt(image)
|
| 706 |
+
|
| 707 |
+
height, width = self.get_default_height_width(image, height, width)
|
| 708 |
+
if self.config.do_resize:
|
| 709 |
+
image = self.resize(image, height, width)
|
| 710 |
+
|
| 711 |
+
elif isinstance(image[0], torch.Tensor):
|
| 712 |
+
image = torch.cat(image, axis=0) if image[0].ndim == 4 else torch.stack(image, axis=0)
|
| 713 |
+
|
| 714 |
+
if self.config.do_convert_grayscale and image.ndim == 3:
|
| 715 |
+
image = image.unsqueeze(1)
|
| 716 |
+
|
| 717 |
+
channel = image.shape[1]
|
| 718 |
+
# don't need any preprocess if the image is latents
|
| 719 |
+
if channel == self.config.vae_latent_channels:
|
| 720 |
+
return image
|
| 721 |
+
|
| 722 |
+
height, width = self.get_default_height_width(image, height, width)
|
| 723 |
+
if self.config.do_resize:
|
| 724 |
+
image = self.resize(image, height, width)
|
| 725 |
+
|
| 726 |
+
# expected range [0,1], normalize to [-1,1]
|
| 727 |
+
do_normalize = self.config.do_normalize
|
| 728 |
+
if do_normalize and image.min() < 0:
|
| 729 |
+
warnings.warn(
|
| 730 |
+
"Passing `image` as torch tensor with value range in [-1,1] is deprecated. The expected value range for image tensor is [0,1] "
|
| 731 |
+
f"when passing as pytorch tensor or numpy Array. You passed `image` with value range [{image.min()},{image.max()}]",
|
| 732 |
+
FutureWarning,
|
| 733 |
+
)
|
| 734 |
+
do_normalize = False
|
| 735 |
+
if do_normalize:
|
| 736 |
+
image = self.normalize(image)
|
| 737 |
+
|
| 738 |
+
if self.config.do_binarize:
|
| 739 |
+
image = self.binarize(image)
|
| 740 |
+
|
| 741 |
+
return image
|
| 742 |
+
|
| 743 |
+
def postprocess(
|
| 744 |
+
self,
|
| 745 |
+
image: torch.Tensor,
|
| 746 |
+
output_type: str = "pil",
|
| 747 |
+
do_denormalize: Optional[List[bool]] = None,
|
| 748 |
+
) -> Union[PIL.Image.Image, np.ndarray, torch.Tensor]:
|
| 749 |
+
"""
|
| 750 |
+
Postprocess the image output from tensor to `output_type`.
|
| 751 |
+
|
| 752 |
+
Args:
|
| 753 |
+
image (`torch.Tensor`):
|
| 754 |
+
The image input, should be a pytorch tensor with shape `B x C x H x W`.
|
| 755 |
+
output_type (`str`, *optional*, defaults to `pil`):
|
| 756 |
+
The output type of the image, can be one of `pil`, `np`, `pt`, `latent`.
|
| 757 |
+
do_denormalize (`List[bool]`, *optional*, defaults to `None`):
|
| 758 |
+
Whether to denormalize the image to [0,1]. If `None`, will use the value of `do_normalize` in the
|
| 759 |
+
`VaeImageProcessor` config.
|
| 760 |
+
|
| 761 |
+
Returns:
|
| 762 |
+
`PIL.Image.Image`, `np.ndarray` or `torch.Tensor`:
|
| 763 |
+
The postprocessed image.
|
| 764 |
+
"""
|
| 765 |
+
if not isinstance(image, torch.Tensor):
|
| 766 |
+
raise ValueError(
|
| 767 |
+
f"Input for postprocessing is in incorrect format: {type(image)}. We only support pytorch tensor"
|
| 768 |
+
)
|
| 769 |
+
if output_type not in ["latent", "pt", "np", "pil"]:
|
| 770 |
+
deprecation_message = (
|
| 771 |
+
f"the output_type {output_type} is outdated and has been set to `np`. Please make sure to set it to one of these instead: "
|
| 772 |
+
"`pil`, `np`, `pt`, `latent`"
|
| 773 |
+
)
|
| 774 |
+
deprecate("Unsupported output_type", "1.0.0", deprecation_message, standard_warn=False)
|
| 775 |
+
output_type = "np"
|
| 776 |
+
|
| 777 |
+
if output_type == "latent":
|
| 778 |
+
return image
|
| 779 |
+
|
| 780 |
+
image = self._denormalize_conditionally(image, do_denormalize)
|
| 781 |
+
|
| 782 |
+
if output_type == "pt":
|
| 783 |
+
return image
|
| 784 |
+
|
| 785 |
+
image = self.pt_to_numpy(image)
|
| 786 |
+
|
| 787 |
+
if output_type == "np":
|
| 788 |
+
return image
|
| 789 |
+
|
| 790 |
+
if output_type == "pil":
|
| 791 |
+
return self.numpy_to_pil(image)
|
| 792 |
+
|
| 793 |
+
def apply_overlay(
|
| 794 |
+
self,
|
| 795 |
+
mask: PIL.Image.Image,
|
| 796 |
+
init_image: PIL.Image.Image,
|
| 797 |
+
image: PIL.Image.Image,
|
| 798 |
+
crop_coords: Optional[Tuple[int, int, int, int]] = None,
|
| 799 |
+
) -> PIL.Image.Image:
|
| 800 |
+
r"""
|
| 801 |
+
Applies an overlay of the mask and the inpainted image on the original image.
|
| 802 |
+
|
| 803 |
+
Args:
|
| 804 |
+
mask (`PIL.Image.Image`):
|
| 805 |
+
The mask image that highlights regions to overlay.
|
| 806 |
+
init_image (`PIL.Image.Image`):
|
| 807 |
+
The original image to which the overlay is applied.
|
| 808 |
+
image (`PIL.Image.Image`):
|
| 809 |
+
The image to overlay onto the original.
|
| 810 |
+
crop_coords (`Tuple[int, int, int, int]`, *optional*):
|
| 811 |
+
Coordinates to crop the image. If provided, the image will be cropped accordingly.
|
| 812 |
+
|
| 813 |
+
Returns:
|
| 814 |
+
`PIL.Image.Image`:
|
| 815 |
+
The final image with the overlay applied.
|
| 816 |
+
"""
|
| 817 |
+
|
| 818 |
+
width, height = init_image.width, init_image.height
|
| 819 |
+
|
| 820 |
+
init_image_masked = PIL.Image.new("RGBa", (width, height))
|
| 821 |
+
init_image_masked.paste(init_image.convert("RGBA").convert("RGBa"), mask=ImageOps.invert(mask.convert("L")))
|
| 822 |
+
|
| 823 |
+
init_image_masked = init_image_masked.convert("RGBA")
|
| 824 |
+
|
| 825 |
+
if crop_coords is not None:
|
| 826 |
+
x, y, x2, y2 = crop_coords
|
| 827 |
+
w = x2 - x
|
| 828 |
+
h = y2 - y
|
| 829 |
+
base_image = PIL.Image.new("RGBA", (width, height))
|
| 830 |
+
image = self.resize(image, height=h, width=w, resize_mode="crop")
|
| 831 |
+
base_image.paste(image, (x, y))
|
| 832 |
+
image = base_image.convert("RGB")
|
| 833 |
+
|
| 834 |
+
image = image.convert("RGBA")
|
| 835 |
+
image.alpha_composite(init_image_masked)
|
| 836 |
+
image = image.convert("RGB")
|
| 837 |
+
|
| 838 |
+
return image
|
| 839 |
+
|
| 840 |
+
|
| 841 |
+
class VaeImageProcessorLDM3D(VaeImageProcessor):
|
| 842 |
+
"""
|
| 843 |
+
Image processor for VAE LDM3D.
|
| 844 |
+
|
| 845 |
+
Args:
|
| 846 |
+
do_resize (`bool`, *optional*, defaults to `True`):
|
| 847 |
+
Whether to downscale the image's (height, width) dimensions to multiples of `vae_scale_factor`.
|
| 848 |
+
vae_scale_factor (`int`, *optional*, defaults to `8`):
|
| 849 |
+
VAE scale factor. If `do_resize` is `True`, the image is automatically resized to multiples of this factor.
|
| 850 |
+
resample (`str`, *optional*, defaults to `lanczos`):
|
| 851 |
+
Resampling filter to use when resizing the image.
|
| 852 |
+
do_normalize (`bool`, *optional*, defaults to `True`):
|
| 853 |
+
Whether to normalize the image to [-1,1].
|
| 854 |
+
"""
|
| 855 |
+
|
| 856 |
+
config_name = CONFIG_NAME
|
| 857 |
+
|
| 858 |
+
@register_to_config
|
| 859 |
+
def __init__(
|
| 860 |
+
self,
|
| 861 |
+
do_resize: bool = True,
|
| 862 |
+
vae_scale_factor: int = 8,
|
| 863 |
+
resample: str = "lanczos",
|
| 864 |
+
do_normalize: bool = True,
|
| 865 |
+
):
|
| 866 |
+
super().__init__()
|
| 867 |
+
|
| 868 |
+
@staticmethod
|
| 869 |
+
def numpy_to_pil(images: np.ndarray) -> List[PIL.Image.Image]:
|
| 870 |
+
r"""
|
| 871 |
+
Convert a NumPy image or a batch of images to a list of PIL images.
|
| 872 |
+
|
| 873 |
+
Args:
|
| 874 |
+
images (`np.ndarray`):
|
| 875 |
+
The input NumPy array of images, which can be a single image or a batch.
|
| 876 |
+
|
| 877 |
+
Returns:
|
| 878 |
+
`List[PIL.Image.Image]`:
|
| 879 |
+
A list of PIL images converted from the input NumPy array.
|
| 880 |
+
"""
|
| 881 |
+
if images.ndim == 3:
|
| 882 |
+
images = images[None, ...]
|
| 883 |
+
images = (images * 255).round().astype("uint8")
|
| 884 |
+
if images.shape[-1] == 1:
|
| 885 |
+
# special case for grayscale (single channel) images
|
| 886 |
+
pil_images = [Image.fromarray(image.squeeze(), mode="L") for image in images]
|
| 887 |
+
else:
|
| 888 |
+
pil_images = [Image.fromarray(image[:, :, :3]) for image in images]
|
| 889 |
+
|
| 890 |
+
return pil_images
|
| 891 |
+
|
| 892 |
+
@staticmethod
|
| 893 |
+
def depth_pil_to_numpy(images: Union[List[PIL.Image.Image], PIL.Image.Image]) -> np.ndarray:
|
| 894 |
+
r"""
|
| 895 |
+
Convert a PIL image or a list of PIL images to NumPy arrays.
|
| 896 |
+
|
| 897 |
+
Args:
|
| 898 |
+
images (`Union[List[PIL.Image.Image], PIL.Image.Image]`):
|
| 899 |
+
The input image or list of images to be converted.
|
| 900 |
+
|
| 901 |
+
Returns:
|
| 902 |
+
`np.ndarray`:
|
| 903 |
+
A NumPy array of the converted images.
|
| 904 |
+
"""
|
| 905 |
+
if not isinstance(images, list):
|
| 906 |
+
images = [images]
|
| 907 |
+
|
| 908 |
+
images = [np.array(image).astype(np.float32) / (2**16 - 1) for image in images]
|
| 909 |
+
images = np.stack(images, axis=0)
|
| 910 |
+
return images
|
| 911 |
+
|
| 912 |
+
@staticmethod
|
| 913 |
+
def rgblike_to_depthmap(image: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]:
|
| 914 |
+
r"""
|
| 915 |
+
Convert an RGB-like depth image to a depth map.
|
| 916 |
+
|
| 917 |
+
Args:
|
| 918 |
+
image (`Union[np.ndarray, torch.Tensor]`):
|
| 919 |
+
The RGB-like depth image to convert.
|
| 920 |
+
|
| 921 |
+
Returns:
|
| 922 |
+
`Union[np.ndarray, torch.Tensor]`:
|
| 923 |
+
The corresponding depth map.
|
| 924 |
+
"""
|
| 925 |
+
return image[:, :, 1] * 2**8 + image[:, :, 2]
|
| 926 |
+
|
| 927 |
+
def numpy_to_depth(self, images: np.ndarray) -> List[PIL.Image.Image]:
|
| 928 |
+
r"""
|
| 929 |
+
Convert a NumPy depth image or a batch of images to a list of PIL images.
|
| 930 |
+
|
| 931 |
+
Args:
|
| 932 |
+
images (`np.ndarray`):
|
| 933 |
+
The input NumPy array of depth images, which can be a single image or a batch.
|
| 934 |
+
|
| 935 |
+
Returns:
|
| 936 |
+
`List[PIL.Image.Image]`:
|
| 937 |
+
A list of PIL images converted from the input NumPy depth images.
|
| 938 |
+
"""
|
| 939 |
+
if images.ndim == 3:
|
| 940 |
+
images = images[None, ...]
|
| 941 |
+
images_depth = images[:, :, :, 3:]
|
| 942 |
+
if images.shape[-1] == 6:
|
| 943 |
+
images_depth = (images_depth * 255).round().astype("uint8")
|
| 944 |
+
pil_images = [
|
| 945 |
+
Image.fromarray(self.rgblike_to_depthmap(image_depth), mode="I;16") for image_depth in images_depth
|
| 946 |
+
]
|
| 947 |
+
elif images.shape[-1] == 4:
|
| 948 |
+
images_depth = (images_depth * 65535.0).astype(np.uint16)
|
| 949 |
+
pil_images = [Image.fromarray(image_depth, mode="I;16") for image_depth in images_depth]
|
| 950 |
+
else:
|
| 951 |
+
raise Exception("Not supported")
|
| 952 |
+
|
| 953 |
+
return pil_images
|
| 954 |
+
|
| 955 |
+
def postprocess(
|
| 956 |
+
self,
|
| 957 |
+
image: torch.Tensor,
|
| 958 |
+
output_type: str = "pil",
|
| 959 |
+
do_denormalize: Optional[List[bool]] = None,
|
| 960 |
+
) -> Union[PIL.Image.Image, np.ndarray, torch.Tensor]:
|
| 961 |
+
"""
|
| 962 |
+
Postprocess the image output from tensor to `output_type`.
|
| 963 |
+
|
| 964 |
+
Args:
|
| 965 |
+
image (`torch.Tensor`):
|
| 966 |
+
The image input, should be a pytorch tensor with shape `B x C x H x W`.
|
| 967 |
+
output_type (`str`, *optional*, defaults to `pil`):
|
| 968 |
+
The output type of the image, can be one of `pil`, `np`, `pt`, `latent`.
|
| 969 |
+
do_denormalize (`List[bool]`, *optional*, defaults to `None`):
|
| 970 |
+
Whether to denormalize the image to [0,1]. If `None`, will use the value of `do_normalize` in the
|
| 971 |
+
`VaeImageProcessor` config.
|
| 972 |
+
|
| 973 |
+
Returns:
|
| 974 |
+
`PIL.Image.Image`, `np.ndarray` or `torch.Tensor`:
|
| 975 |
+
The postprocessed image.
|
| 976 |
+
"""
|
| 977 |
+
if not isinstance(image, torch.Tensor):
|
| 978 |
+
raise ValueError(
|
| 979 |
+
f"Input for postprocessing is in incorrect format: {type(image)}. We only support pytorch tensor"
|
| 980 |
+
)
|
| 981 |
+
if output_type not in ["latent", "pt", "np", "pil"]:
|
| 982 |
+
deprecation_message = (
|
| 983 |
+
f"the output_type {output_type} is outdated and has been set to `np`. Please make sure to set it to one of these instead: "
|
| 984 |
+
"`pil`, `np`, `pt`, `latent`"
|
| 985 |
+
)
|
| 986 |
+
deprecate("Unsupported output_type", "1.0.0", deprecation_message, standard_warn=False)
|
| 987 |
+
output_type = "np"
|
| 988 |
+
|
| 989 |
+
image = self._denormalize_conditionally(image, do_denormalize)
|
| 990 |
+
|
| 991 |
+
image = self.pt_to_numpy(image)
|
| 992 |
+
|
| 993 |
+
if output_type == "np":
|
| 994 |
+
if image.shape[-1] == 6:
|
| 995 |
+
image_depth = np.stack([self.rgblike_to_depthmap(im[:, :, 3:]) for im in image], axis=0)
|
| 996 |
+
else:
|
| 997 |
+
image_depth = image[:, :, :, 3:]
|
| 998 |
+
return image[:, :, :, :3], image_depth
|
| 999 |
+
|
| 1000 |
+
if output_type == "pil":
|
| 1001 |
+
return self.numpy_to_pil(image), self.numpy_to_depth(image)
|
| 1002 |
+
else:
|
| 1003 |
+
raise Exception(f"This type {output_type} is not supported")
|
| 1004 |
+
|
| 1005 |
+
def preprocess(
|
| 1006 |
+
self,
|
| 1007 |
+
rgb: Union[torch.Tensor, PIL.Image.Image, np.ndarray],
|
| 1008 |
+
depth: Union[torch.Tensor, PIL.Image.Image, np.ndarray],
|
| 1009 |
+
height: Optional[int] = None,
|
| 1010 |
+
width: Optional[int] = None,
|
| 1011 |
+
target_res: Optional[int] = None,
|
| 1012 |
+
) -> torch.Tensor:
|
| 1013 |
+
r"""
|
| 1014 |
+
Preprocess the image input. Accepted formats are PIL images, NumPy arrays, or PyTorch tensors.
|
| 1015 |
+
|
| 1016 |
+
Args:
|
| 1017 |
+
rgb (`Union[torch.Tensor, PIL.Image.Image, np.ndarray]`):
|
| 1018 |
+
The RGB input image, which can be a single image or a batch.
|
| 1019 |
+
depth (`Union[torch.Tensor, PIL.Image.Image, np.ndarray]`):
|
| 1020 |
+
The depth input image, which can be a single image or a batch.
|
| 1021 |
+
height (`Optional[int]`, *optional*, defaults to `None`):
|
| 1022 |
+
The desired height of the processed image. If `None`, defaults to the height of the input image.
|
| 1023 |
+
width (`Optional[int]`, *optional*, defaults to `None`):
|
| 1024 |
+
The desired width of the processed image. If `None`, defaults to the width of the input image.
|
| 1025 |
+
target_res (`Optional[int]`, *optional*, defaults to `None`):
|
| 1026 |
+
Target resolution for resizing the images. If specified, overrides height and width.
|
| 1027 |
+
|
| 1028 |
+
Returns:
|
| 1029 |
+
`Tuple[torch.Tensor, torch.Tensor]`:
|
| 1030 |
+
A tuple containing the processed RGB and depth images as PyTorch tensors.
|
| 1031 |
+
"""
|
| 1032 |
+
supported_formats = (PIL.Image.Image, np.ndarray, torch.Tensor)
|
| 1033 |
+
|
| 1034 |
+
# Expand the missing dimension for 3-dimensional pytorch tensor or numpy array that represents grayscale image
|
| 1035 |
+
if self.config.do_convert_grayscale and isinstance(rgb, (torch.Tensor, np.ndarray)) and rgb.ndim == 3:
|
| 1036 |
+
raise Exception("This is not yet supported")
|
| 1037 |
+
|
| 1038 |
+
if isinstance(rgb, supported_formats):
|
| 1039 |
+
rgb = [rgb]
|
| 1040 |
+
depth = [depth]
|
| 1041 |
+
elif not (isinstance(rgb, list) and all(isinstance(i, supported_formats) for i in rgb)):
|
| 1042 |
+
raise ValueError(
|
| 1043 |
+
f"Input is in incorrect format: {[type(i) for i in rgb]}. Currently, we only support {', '.join(supported_formats)}"
|
| 1044 |
+
)
|
| 1045 |
+
|
| 1046 |
+
if isinstance(rgb[0], PIL.Image.Image):
|
| 1047 |
+
if self.config.do_convert_rgb:
|
| 1048 |
+
raise Exception("This is not yet supported")
|
| 1049 |
+
# rgb = [self.convert_to_rgb(i) for i in rgb]
|
| 1050 |
+
# depth = [self.convert_to_depth(i) for i in depth] #TODO define convert_to_depth
|
| 1051 |
+
if self.config.do_resize or target_res:
|
| 1052 |
+
height, width = self.get_default_height_width(rgb[0], height, width) if not target_res else target_res
|
| 1053 |
+
rgb = [self.resize(i, height, width) for i in rgb]
|
| 1054 |
+
depth = [self.resize(i, height, width) for i in depth]
|
| 1055 |
+
rgb = self.pil_to_numpy(rgb) # to np
|
| 1056 |
+
rgb = self.numpy_to_pt(rgb) # to pt
|
| 1057 |
+
|
| 1058 |
+
depth = self.depth_pil_to_numpy(depth) # to np
|
| 1059 |
+
depth = self.numpy_to_pt(depth) # to pt
|
| 1060 |
+
|
| 1061 |
+
elif isinstance(rgb[0], np.ndarray):
|
| 1062 |
+
rgb = np.concatenate(rgb, axis=0) if rgb[0].ndim == 4 else np.stack(rgb, axis=0)
|
| 1063 |
+
rgb = self.numpy_to_pt(rgb)
|
| 1064 |
+
height, width = self.get_default_height_width(rgb, height, width)
|
| 1065 |
+
if self.config.do_resize:
|
| 1066 |
+
rgb = self.resize(rgb, height, width)
|
| 1067 |
+
|
| 1068 |
+
depth = np.concatenate(depth, axis=0) if rgb[0].ndim == 4 else np.stack(depth, axis=0)
|
| 1069 |
+
depth = self.numpy_to_pt(depth)
|
| 1070 |
+
height, width = self.get_default_height_width(depth, height, width)
|
| 1071 |
+
if self.config.do_resize:
|
| 1072 |
+
depth = self.resize(depth, height, width)
|
| 1073 |
+
|
| 1074 |
+
elif isinstance(rgb[0], torch.Tensor):
|
| 1075 |
+
raise Exception("This is not yet supported")
|
| 1076 |
+
# rgb = torch.cat(rgb, axis=0) if rgb[0].ndim == 4 else torch.stack(rgb, axis=0)
|
| 1077 |
+
|
| 1078 |
+
# if self.config.do_convert_grayscale and rgb.ndim == 3:
|
| 1079 |
+
# rgb = rgb.unsqueeze(1)
|
| 1080 |
+
|
| 1081 |
+
# channel = rgb.shape[1]
|
| 1082 |
+
|
| 1083 |
+
# height, width = self.get_default_height_width(rgb, height, width)
|
| 1084 |
+
# if self.config.do_resize:
|
| 1085 |
+
# rgb = self.resize(rgb, height, width)
|
| 1086 |
+
|
| 1087 |
+
# depth = torch.cat(depth, axis=0) if depth[0].ndim == 4 else torch.stack(depth, axis=0)
|
| 1088 |
+
|
| 1089 |
+
# if self.config.do_convert_grayscale and depth.ndim == 3:
|
| 1090 |
+
# depth = depth.unsqueeze(1)
|
| 1091 |
+
|
| 1092 |
+
# channel = depth.shape[1]
|
| 1093 |
+
# # don't need any preprocess if the image is latents
|
| 1094 |
+
# if depth == 4:
|
| 1095 |
+
# return rgb, depth
|
| 1096 |
+
|
| 1097 |
+
# height, width = self.get_default_height_width(depth, height, width)
|
| 1098 |
+
# if self.config.do_resize:
|
| 1099 |
+
# depth = self.resize(depth, height, width)
|
| 1100 |
+
# expected range [0,1], normalize to [-1,1]
|
| 1101 |
+
do_normalize = self.config.do_normalize
|
| 1102 |
+
if rgb.min() < 0 and do_normalize:
|
| 1103 |
+
warnings.warn(
|
| 1104 |
+
"Passing `image` as torch tensor with value range in [-1,1] is deprecated. The expected value range for image tensor is [0,1] "
|
| 1105 |
+
f"when passing as pytorch tensor or numpy Array. You passed `image` with value range [{rgb.min()},{rgb.max()}]",
|
| 1106 |
+
FutureWarning,
|
| 1107 |
+
)
|
| 1108 |
+
do_normalize = False
|
| 1109 |
+
|
| 1110 |
+
if do_normalize:
|
| 1111 |
+
rgb = self.normalize(rgb)
|
| 1112 |
+
depth = self.normalize(depth)
|
| 1113 |
+
|
| 1114 |
+
if self.config.do_binarize:
|
| 1115 |
+
rgb = self.binarize(rgb)
|
| 1116 |
+
depth = self.binarize(depth)
|
| 1117 |
+
|
| 1118 |
+
return rgb, depth
|
| 1119 |
+
|
| 1120 |
+
|
| 1121 |
+
class IPAdapterMaskProcessor(VaeImageProcessor):
|
| 1122 |
+
"""
|
| 1123 |
+
Image processor for IP Adapter image masks.
|
| 1124 |
+
|
| 1125 |
+
Args:
|
| 1126 |
+
do_resize (`bool`, *optional*, defaults to `True`):
|
| 1127 |
+
Whether to downscale the image's (height, width) dimensions to multiples of `vae_scale_factor`.
|
| 1128 |
+
vae_scale_factor (`int`, *optional*, defaults to `8`):
|
| 1129 |
+
VAE scale factor. If `do_resize` is `True`, the image is automatically resized to multiples of this factor.
|
| 1130 |
+
resample (`str`, *optional*, defaults to `lanczos`):
|
| 1131 |
+
Resampling filter to use when resizing the image.
|
| 1132 |
+
do_normalize (`bool`, *optional*, defaults to `False`):
|
| 1133 |
+
Whether to normalize the image to [-1,1].
|
| 1134 |
+
do_binarize (`bool`, *optional*, defaults to `True`):
|
| 1135 |
+
Whether to binarize the image to 0/1.
|
| 1136 |
+
do_convert_grayscale (`bool`, *optional*, defaults to be `True`):
|
| 1137 |
+
Whether to convert the images to grayscale format.
|
| 1138 |
+
|
| 1139 |
+
"""
|
| 1140 |
+
|
| 1141 |
+
config_name = CONFIG_NAME
|
| 1142 |
+
|
| 1143 |
+
@register_to_config
|
| 1144 |
+
def __init__(
|
| 1145 |
+
self,
|
| 1146 |
+
do_resize: bool = True,
|
| 1147 |
+
vae_scale_factor: int = 8,
|
| 1148 |
+
resample: str = "lanczos",
|
| 1149 |
+
do_normalize: bool = False,
|
| 1150 |
+
do_binarize: bool = True,
|
| 1151 |
+
do_convert_grayscale: bool = True,
|
| 1152 |
+
):
|
| 1153 |
+
super().__init__(
|
| 1154 |
+
do_resize=do_resize,
|
| 1155 |
+
vae_scale_factor=vae_scale_factor,
|
| 1156 |
+
resample=resample,
|
| 1157 |
+
do_normalize=do_normalize,
|
| 1158 |
+
do_binarize=do_binarize,
|
| 1159 |
+
do_convert_grayscale=do_convert_grayscale,
|
| 1160 |
+
)
|
| 1161 |
+
|
| 1162 |
+
@staticmethod
|
| 1163 |
+
def downsample(mask: torch.Tensor, batch_size: int, num_queries: int, value_embed_dim: int):
|
| 1164 |
+
"""
|
| 1165 |
+
Downsamples the provided mask tensor to match the expected dimensions for scaled dot-product attention. If the
|
| 1166 |
+
aspect ratio of the mask does not match the aspect ratio of the output image, a warning is issued.
|
| 1167 |
+
|
| 1168 |
+
Args:
|
| 1169 |
+
mask (`torch.Tensor`):
|
| 1170 |
+
The input mask tensor generated with `IPAdapterMaskProcessor.preprocess()`.
|
| 1171 |
+
batch_size (`int`):
|
| 1172 |
+
The batch size.
|
| 1173 |
+
num_queries (`int`):
|
| 1174 |
+
The number of queries.
|
| 1175 |
+
value_embed_dim (`int`):
|
| 1176 |
+
The dimensionality of the value embeddings.
|
| 1177 |
+
|
| 1178 |
+
Returns:
|
| 1179 |
+
`torch.Tensor`:
|
| 1180 |
+
The downsampled mask tensor.
|
| 1181 |
+
|
| 1182 |
+
"""
|
| 1183 |
+
o_h = mask.shape[1]
|
| 1184 |
+
o_w = mask.shape[2]
|
| 1185 |
+
ratio = o_w / o_h
|
| 1186 |
+
mask_h = int(math.sqrt(num_queries / ratio))
|
| 1187 |
+
mask_h = int(mask_h) + int((num_queries % int(mask_h)) != 0)
|
| 1188 |
+
mask_w = num_queries // mask_h
|
| 1189 |
+
|
| 1190 |
+
mask_downsample = F.interpolate(mask.unsqueeze(0), size=(mask_h, mask_w), mode="bicubic").squeeze(0)
|
| 1191 |
+
|
| 1192 |
+
# Repeat batch_size times
|
| 1193 |
+
if mask_downsample.shape[0] < batch_size:
|
| 1194 |
+
mask_downsample = mask_downsample.repeat(batch_size, 1, 1)
|
| 1195 |
+
|
| 1196 |
+
mask_downsample = mask_downsample.view(mask_downsample.shape[0], -1)
|
| 1197 |
+
|
| 1198 |
+
downsampled_area = mask_h * mask_w
|
| 1199 |
+
# If the output image and the mask do not have the same aspect ratio, tensor shapes will not match
|
| 1200 |
+
# Pad tensor if downsampled_mask.shape[1] is smaller than num_queries
|
| 1201 |
+
if downsampled_area < num_queries:
|
| 1202 |
+
warnings.warn(
|
| 1203 |
+
"The aspect ratio of the mask does not match the aspect ratio of the output image. "
|
| 1204 |
+
"Please update your masks or adjust the output size for optimal performance.",
|
| 1205 |
+
UserWarning,
|
| 1206 |
+
)
|
| 1207 |
+
mask_downsample = F.pad(mask_downsample, (0, num_queries - mask_downsample.shape[1]), value=0.0)
|
| 1208 |
+
# Discard last embeddings if downsampled_mask.shape[1] is bigger than num_queries
|
| 1209 |
+
if downsampled_area > num_queries:
|
| 1210 |
+
warnings.warn(
|
| 1211 |
+
"The aspect ratio of the mask does not match the aspect ratio of the output image. "
|
| 1212 |
+
"Please update your masks or adjust the output size for optimal performance.",
|
| 1213 |
+
UserWarning,
|
| 1214 |
+
)
|
| 1215 |
+
mask_downsample = mask_downsample[:, :num_queries]
|
| 1216 |
+
|
| 1217 |
+
# Repeat last dimension to match SDPA output shape
|
| 1218 |
+
mask_downsample = mask_downsample.view(mask_downsample.shape[0], mask_downsample.shape[1], 1).repeat(
|
| 1219 |
+
1, 1, value_embed_dim
|
| 1220 |
+
)
|
| 1221 |
+
|
| 1222 |
+
return mask_downsample
|
| 1223 |
+
|
| 1224 |
+
|
| 1225 |
+
class PixArtImageProcessor(VaeImageProcessor):
|
| 1226 |
+
"""
|
| 1227 |
+
Image processor for PixArt image resize and crop.
|
| 1228 |
+
|
| 1229 |
+
Args:
|
| 1230 |
+
do_resize (`bool`, *optional*, defaults to `True`):
|
| 1231 |
+
Whether to downscale the image's (height, width) dimensions to multiples of `vae_scale_factor`. Can accept
|
| 1232 |
+
`height` and `width` arguments from [`image_processor.VaeImageProcessor.preprocess`] method.
|
| 1233 |
+
vae_scale_factor (`int`, *optional*, defaults to `8`):
|
| 1234 |
+
VAE scale factor. If `do_resize` is `True`, the image is automatically resized to multiples of this factor.
|
| 1235 |
+
resample (`str`, *optional*, defaults to `lanczos`):
|
| 1236 |
+
Resampling filter to use when resizing the image.
|
| 1237 |
+
do_normalize (`bool`, *optional*, defaults to `True`):
|
| 1238 |
+
Whether to normalize the image to [-1,1].
|
| 1239 |
+
do_binarize (`bool`, *optional*, defaults to `False`):
|
| 1240 |
+
Whether to binarize the image to 0/1.
|
| 1241 |
+
do_convert_rgb (`bool`, *optional*, defaults to be `False`):
|
| 1242 |
+
Whether to convert the images to RGB format.
|
| 1243 |
+
do_convert_grayscale (`bool`, *optional*, defaults to be `False`):
|
| 1244 |
+
Whether to convert the images to grayscale format.
|
| 1245 |
+
"""
|
| 1246 |
+
|
| 1247 |
+
@register_to_config
|
| 1248 |
+
def __init__(
|
| 1249 |
+
self,
|
| 1250 |
+
do_resize: bool = True,
|
| 1251 |
+
vae_scale_factor: int = 8,
|
| 1252 |
+
resample: str = "lanczos",
|
| 1253 |
+
do_normalize: bool = True,
|
| 1254 |
+
do_binarize: bool = False,
|
| 1255 |
+
do_convert_grayscale: bool = False,
|
| 1256 |
+
):
|
| 1257 |
+
super().__init__(
|
| 1258 |
+
do_resize=do_resize,
|
| 1259 |
+
vae_scale_factor=vae_scale_factor,
|
| 1260 |
+
resample=resample,
|
| 1261 |
+
do_normalize=do_normalize,
|
| 1262 |
+
do_binarize=do_binarize,
|
| 1263 |
+
do_convert_grayscale=do_convert_grayscale,
|
| 1264 |
+
)
|
| 1265 |
+
|
| 1266 |
+
@staticmethod
|
| 1267 |
+
def classify_height_width_bin(height: int, width: int, ratios: dict) -> Tuple[int, int]:
|
| 1268 |
+
r"""
|
| 1269 |
+
Returns the binned height and width based on the aspect ratio.
|
| 1270 |
+
|
| 1271 |
+
Args:
|
| 1272 |
+
height (`int`): The height of the image.
|
| 1273 |
+
width (`int`): The width of the image.
|
| 1274 |
+
ratios (`dict`): A dictionary where keys are aspect ratios and values are tuples of (height, width).
|
| 1275 |
+
|
| 1276 |
+
Returns:
|
| 1277 |
+
`Tuple[int, int]`: The closest binned height and width.
|
| 1278 |
+
"""
|
| 1279 |
+
ar = float(height / width)
|
| 1280 |
+
closest_ratio = min(ratios.keys(), key=lambda ratio: abs(float(ratio) - ar))
|
| 1281 |
+
default_hw = ratios[closest_ratio]
|
| 1282 |
+
return int(default_hw[0]), int(default_hw[1])
|
| 1283 |
+
|
| 1284 |
+
@staticmethod
|
| 1285 |
+
def resize_and_crop_tensor(samples: torch.Tensor, new_width: int, new_height: int) -> torch.Tensor:
|
| 1286 |
+
r"""
|
| 1287 |
+
Resizes and crops a tensor of images to the specified dimensions.
|
| 1288 |
+
|
| 1289 |
+
Args:
|
| 1290 |
+
samples (`torch.Tensor`):
|
| 1291 |
+
A tensor of shape (N, C, H, W) where N is the batch size, C is the number of channels, H is the height,
|
| 1292 |
+
and W is the width.
|
| 1293 |
+
new_width (`int`): The desired width of the output images.
|
| 1294 |
+
new_height (`int`): The desired height of the output images.
|
| 1295 |
+
|
| 1296 |
+
Returns:
|
| 1297 |
+
`torch.Tensor`: A tensor containing the resized and cropped images.
|
| 1298 |
+
"""
|
| 1299 |
+
orig_height, orig_width = samples.shape[2], samples.shape[3]
|
| 1300 |
+
|
| 1301 |
+
# Check if resizing is needed
|
| 1302 |
+
if orig_height != new_height or orig_width != new_width:
|
| 1303 |
+
ratio = max(new_height / orig_height, new_width / orig_width)
|
| 1304 |
+
resized_width = int(orig_width * ratio)
|
| 1305 |
+
resized_height = int(orig_height * ratio)
|
| 1306 |
+
|
| 1307 |
+
# Resize
|
| 1308 |
+
samples = F.interpolate(
|
| 1309 |
+
samples, size=(resized_height, resized_width), mode="bilinear", align_corners=False
|
| 1310 |
+
)
|
| 1311 |
+
|
| 1312 |
+
# Center Crop
|
| 1313 |
+
start_x = (resized_width - new_width) // 2
|
| 1314 |
+
end_x = start_x + new_width
|
| 1315 |
+
start_y = (resized_height - new_height) // 2
|
| 1316 |
+
end_y = start_y + new_height
|
| 1317 |
+
samples = samples[:, :, start_y:end_y, start_x:end_x]
|
| 1318 |
+
|
| 1319 |
+
return samples
|
venv/lib/python3.10/site-packages/diffusers/optimization.py
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""PyTorch optimization for diffusion models."""
|
| 16 |
+
|
| 17 |
+
import math
|
| 18 |
+
from enum import Enum
|
| 19 |
+
from typing import Optional, Union
|
| 20 |
+
|
| 21 |
+
from torch.optim import Optimizer
|
| 22 |
+
from torch.optim.lr_scheduler import LambdaLR
|
| 23 |
+
|
| 24 |
+
from .utils import logging
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
logger = logging.get_logger(__name__)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class SchedulerType(Enum):
|
| 31 |
+
LINEAR = "linear"
|
| 32 |
+
COSINE = "cosine"
|
| 33 |
+
COSINE_WITH_RESTARTS = "cosine_with_restarts"
|
| 34 |
+
POLYNOMIAL = "polynomial"
|
| 35 |
+
CONSTANT = "constant"
|
| 36 |
+
CONSTANT_WITH_WARMUP = "constant_with_warmup"
|
| 37 |
+
PIECEWISE_CONSTANT = "piecewise_constant"
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def get_constant_schedule(optimizer: Optimizer, last_epoch: int = -1) -> LambdaLR:
|
| 41 |
+
"""
|
| 42 |
+
Create a schedule with a constant learning rate, using the learning rate set in optimizer.
|
| 43 |
+
|
| 44 |
+
Args:
|
| 45 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 46 |
+
The optimizer for which to schedule the learning rate.
|
| 47 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 48 |
+
The index of the last epoch when resuming training.
|
| 49 |
+
|
| 50 |
+
Return:
|
| 51 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 52 |
+
"""
|
| 53 |
+
return LambdaLR(optimizer, lambda _: 1, last_epoch=last_epoch)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def get_constant_schedule_with_warmup(optimizer: Optimizer, num_warmup_steps: int, last_epoch: int = -1) -> LambdaLR:
|
| 57 |
+
"""
|
| 58 |
+
Create a schedule with a constant learning rate preceded by a warmup period during which the learning rate
|
| 59 |
+
increases linearly between 0 and the initial lr set in the optimizer.
|
| 60 |
+
|
| 61 |
+
Args:
|
| 62 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 63 |
+
The optimizer for which to schedule the learning rate.
|
| 64 |
+
num_warmup_steps (`int`):
|
| 65 |
+
The number of steps for the warmup phase.
|
| 66 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 67 |
+
The index of the last epoch when resuming training.
|
| 68 |
+
|
| 69 |
+
Return:
|
| 70 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 71 |
+
"""
|
| 72 |
+
|
| 73 |
+
def lr_lambda(current_step: int):
|
| 74 |
+
if current_step < num_warmup_steps:
|
| 75 |
+
return float(current_step) / float(max(1.0, num_warmup_steps))
|
| 76 |
+
return 1.0
|
| 77 |
+
|
| 78 |
+
return LambdaLR(optimizer, lr_lambda, last_epoch=last_epoch)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def get_piecewise_constant_schedule(optimizer: Optimizer, step_rules: str, last_epoch: int = -1) -> LambdaLR:
|
| 82 |
+
"""
|
| 83 |
+
Create a schedule with a constant learning rate, using the learning rate set in optimizer.
|
| 84 |
+
|
| 85 |
+
Args:
|
| 86 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 87 |
+
The optimizer for which to schedule the learning rate.
|
| 88 |
+
step_rules (`string`):
|
| 89 |
+
The rules for the learning rate. ex: rule_steps="1:10,0.1:20,0.01:30,0.005" it means that the learning rate
|
| 90 |
+
if multiple 1 for the first 10 steps, multiple 0.1 for the next 20 steps, multiple 0.01 for the next 30
|
| 91 |
+
steps and multiple 0.005 for the other steps.
|
| 92 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 93 |
+
The index of the last epoch when resuming training.
|
| 94 |
+
|
| 95 |
+
Return:
|
| 96 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 97 |
+
"""
|
| 98 |
+
|
| 99 |
+
rules_dict = {}
|
| 100 |
+
rule_list = step_rules.split(",")
|
| 101 |
+
for rule_str in rule_list[:-1]:
|
| 102 |
+
value_str, steps_str = rule_str.split(":")
|
| 103 |
+
steps = int(steps_str)
|
| 104 |
+
value = float(value_str)
|
| 105 |
+
rules_dict[steps] = value
|
| 106 |
+
last_lr_multiple = float(rule_list[-1])
|
| 107 |
+
|
| 108 |
+
def create_rules_function(rules_dict, last_lr_multiple):
|
| 109 |
+
def rule_func(steps: int) -> float:
|
| 110 |
+
sorted_steps = sorted(rules_dict.keys())
|
| 111 |
+
for i, sorted_step in enumerate(sorted_steps):
|
| 112 |
+
if steps < sorted_step:
|
| 113 |
+
return rules_dict[sorted_steps[i]]
|
| 114 |
+
return last_lr_multiple
|
| 115 |
+
|
| 116 |
+
return rule_func
|
| 117 |
+
|
| 118 |
+
rules_func = create_rules_function(rules_dict, last_lr_multiple)
|
| 119 |
+
|
| 120 |
+
return LambdaLR(optimizer, rules_func, last_epoch=last_epoch)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def get_linear_schedule_with_warmup(
|
| 124 |
+
optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, last_epoch: int = -1
|
| 125 |
+
) -> LambdaLR:
|
| 126 |
+
"""
|
| 127 |
+
Create a schedule with a learning rate that decreases linearly from the initial lr set in the optimizer to 0, after
|
| 128 |
+
a warmup period during which it increases linearly from 0 to the initial lr set in the optimizer.
|
| 129 |
+
|
| 130 |
+
Args:
|
| 131 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 132 |
+
The optimizer for which to schedule the learning rate.
|
| 133 |
+
num_warmup_steps (`int`):
|
| 134 |
+
The number of steps for the warmup phase.
|
| 135 |
+
num_training_steps (`int`):
|
| 136 |
+
The total number of training steps.
|
| 137 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 138 |
+
The index of the last epoch when resuming training.
|
| 139 |
+
|
| 140 |
+
Return:
|
| 141 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 142 |
+
"""
|
| 143 |
+
|
| 144 |
+
def lr_lambda(current_step: int):
|
| 145 |
+
if current_step < num_warmup_steps:
|
| 146 |
+
return float(current_step) / float(max(1, num_warmup_steps))
|
| 147 |
+
return max(
|
| 148 |
+
0.0, float(num_training_steps - current_step) / float(max(1, num_training_steps - num_warmup_steps))
|
| 149 |
+
)
|
| 150 |
+
|
| 151 |
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def get_cosine_schedule_with_warmup(
|
| 155 |
+
optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, num_cycles: float = 0.5, last_epoch: int = -1
|
| 156 |
+
) -> LambdaLR:
|
| 157 |
+
"""
|
| 158 |
+
Create a schedule with a learning rate that decreases following the values of the cosine function between the
|
| 159 |
+
initial lr set in the optimizer to 0, after a warmup period during which it increases linearly between 0 and the
|
| 160 |
+
initial lr set in the optimizer.
|
| 161 |
+
|
| 162 |
+
Args:
|
| 163 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 164 |
+
The optimizer for which to schedule the learning rate.
|
| 165 |
+
num_warmup_steps (`int`):
|
| 166 |
+
The number of steps for the warmup phase.
|
| 167 |
+
num_training_steps (`int`):
|
| 168 |
+
The total number of training steps.
|
| 169 |
+
num_periods (`float`, *optional*, defaults to 0.5):
|
| 170 |
+
The number of periods of the cosine function in a schedule (the default is to just decrease from the max
|
| 171 |
+
value to 0 following a half-cosine).
|
| 172 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 173 |
+
The index of the last epoch when resuming training.
|
| 174 |
+
|
| 175 |
+
Return:
|
| 176 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 177 |
+
"""
|
| 178 |
+
|
| 179 |
+
def lr_lambda(current_step):
|
| 180 |
+
if current_step < num_warmup_steps:
|
| 181 |
+
return float(current_step) / float(max(1, num_warmup_steps))
|
| 182 |
+
progress = float(current_step - num_warmup_steps) / float(max(1, num_training_steps - num_warmup_steps))
|
| 183 |
+
return max(0.0, 0.5 * (1.0 + math.cos(math.pi * float(num_cycles) * 2.0 * progress)))
|
| 184 |
+
|
| 185 |
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
def get_cosine_with_hard_restarts_schedule_with_warmup(
|
| 189 |
+
optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, num_cycles: int = 1, last_epoch: int = -1
|
| 190 |
+
) -> LambdaLR:
|
| 191 |
+
"""
|
| 192 |
+
Create a schedule with a learning rate that decreases following the values of the cosine function between the
|
| 193 |
+
initial lr set in the optimizer to 0, with several hard restarts, after a warmup period during which it increases
|
| 194 |
+
linearly between 0 and the initial lr set in the optimizer.
|
| 195 |
+
|
| 196 |
+
Args:
|
| 197 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 198 |
+
The optimizer for which to schedule the learning rate.
|
| 199 |
+
num_warmup_steps (`int`):
|
| 200 |
+
The number of steps for the warmup phase.
|
| 201 |
+
num_training_steps (`int`):
|
| 202 |
+
The total number of training steps.
|
| 203 |
+
num_cycles (`int`, *optional*, defaults to 1):
|
| 204 |
+
The number of hard restarts to use.
|
| 205 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 206 |
+
The index of the last epoch when resuming training.
|
| 207 |
+
|
| 208 |
+
Return:
|
| 209 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 210 |
+
"""
|
| 211 |
+
|
| 212 |
+
def lr_lambda(current_step):
|
| 213 |
+
if current_step < num_warmup_steps:
|
| 214 |
+
return float(current_step) / float(max(1, num_warmup_steps))
|
| 215 |
+
progress = float(current_step - num_warmup_steps) / float(max(1, num_training_steps - num_warmup_steps))
|
| 216 |
+
if progress >= 1.0:
|
| 217 |
+
return 0.0
|
| 218 |
+
return max(0.0, 0.5 * (1.0 + math.cos(math.pi * ((float(num_cycles) * progress) % 1.0))))
|
| 219 |
+
|
| 220 |
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
def get_polynomial_decay_schedule_with_warmup(
|
| 224 |
+
optimizer: Optimizer,
|
| 225 |
+
num_warmup_steps: int,
|
| 226 |
+
num_training_steps: int,
|
| 227 |
+
lr_end: float = 1e-7,
|
| 228 |
+
power: float = 1.0,
|
| 229 |
+
last_epoch: int = -1,
|
| 230 |
+
) -> LambdaLR:
|
| 231 |
+
"""
|
| 232 |
+
Create a schedule with a learning rate that decreases as a polynomial decay from the initial lr set in the
|
| 233 |
+
optimizer to end lr defined by *lr_end*, after a warmup period during which it increases linearly from 0 to the
|
| 234 |
+
initial lr set in the optimizer.
|
| 235 |
+
|
| 236 |
+
Args:
|
| 237 |
+
optimizer ([`~torch.optim.Optimizer`]):
|
| 238 |
+
The optimizer for which to schedule the learning rate.
|
| 239 |
+
num_warmup_steps (`int`):
|
| 240 |
+
The number of steps for the warmup phase.
|
| 241 |
+
num_training_steps (`int`):
|
| 242 |
+
The total number of training steps.
|
| 243 |
+
lr_end (`float`, *optional*, defaults to 1e-7):
|
| 244 |
+
The end LR.
|
| 245 |
+
power (`float`, *optional*, defaults to 1.0):
|
| 246 |
+
Power factor.
|
| 247 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 248 |
+
The index of the last epoch when resuming training.
|
| 249 |
+
|
| 250 |
+
Note: *power* defaults to 1.0 as in the fairseq implementation, which in turn is based on the original BERT
|
| 251 |
+
implementation at
|
| 252 |
+
https://github.com/google-research/bert/blob/f39e881b169b9d53bea03d2d341b31707a6c052b/optimization.py#L37
|
| 253 |
+
|
| 254 |
+
Return:
|
| 255 |
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
| 256 |
+
|
| 257 |
+
"""
|
| 258 |
+
|
| 259 |
+
lr_init = optimizer.defaults["lr"]
|
| 260 |
+
if not (lr_init > lr_end):
|
| 261 |
+
raise ValueError(f"lr_end ({lr_end}) must be smaller than initial lr ({lr_init})")
|
| 262 |
+
|
| 263 |
+
def lr_lambda(current_step: int):
|
| 264 |
+
if current_step < num_warmup_steps:
|
| 265 |
+
return float(current_step) / float(max(1, num_warmup_steps))
|
| 266 |
+
elif current_step > num_training_steps:
|
| 267 |
+
return lr_end / lr_init # as LambdaLR multiplies by lr_init
|
| 268 |
+
else:
|
| 269 |
+
lr_range = lr_init - lr_end
|
| 270 |
+
decay_steps = num_training_steps - num_warmup_steps
|
| 271 |
+
pct_remaining = 1 - (current_step - num_warmup_steps) / decay_steps
|
| 272 |
+
decay = lr_range * pct_remaining**power + lr_end
|
| 273 |
+
return decay / lr_init # as LambdaLR multiplies by lr_init
|
| 274 |
+
|
| 275 |
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
TYPE_TO_SCHEDULER_FUNCTION = {
|
| 279 |
+
SchedulerType.LINEAR: get_linear_schedule_with_warmup,
|
| 280 |
+
SchedulerType.COSINE: get_cosine_schedule_with_warmup,
|
| 281 |
+
SchedulerType.COSINE_WITH_RESTARTS: get_cosine_with_hard_restarts_schedule_with_warmup,
|
| 282 |
+
SchedulerType.POLYNOMIAL: get_polynomial_decay_schedule_with_warmup,
|
| 283 |
+
SchedulerType.CONSTANT: get_constant_schedule,
|
| 284 |
+
SchedulerType.CONSTANT_WITH_WARMUP: get_constant_schedule_with_warmup,
|
| 285 |
+
SchedulerType.PIECEWISE_CONSTANT: get_piecewise_constant_schedule,
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
def get_scheduler(
|
| 290 |
+
name: Union[str, SchedulerType],
|
| 291 |
+
optimizer: Optimizer,
|
| 292 |
+
step_rules: Optional[str] = None,
|
| 293 |
+
num_warmup_steps: Optional[int] = None,
|
| 294 |
+
num_training_steps: Optional[int] = None,
|
| 295 |
+
num_cycles: int = 1,
|
| 296 |
+
power: float = 1.0,
|
| 297 |
+
last_epoch: int = -1,
|
| 298 |
+
) -> LambdaLR:
|
| 299 |
+
"""
|
| 300 |
+
Unified API to get any scheduler from its name.
|
| 301 |
+
|
| 302 |
+
Args:
|
| 303 |
+
name (`str` or `SchedulerType`):
|
| 304 |
+
The name of the scheduler to use.
|
| 305 |
+
optimizer (`torch.optim.Optimizer`):
|
| 306 |
+
The optimizer that will be used during training.
|
| 307 |
+
step_rules (`str`, *optional*):
|
| 308 |
+
A string representing the step rules to use. This is only used by the `PIECEWISE_CONSTANT` scheduler.
|
| 309 |
+
num_warmup_steps (`int`, *optional*):
|
| 310 |
+
The number of warmup steps to do. This is not required by all schedulers (hence the argument being
|
| 311 |
+
optional), the function will raise an error if it's unset and the scheduler type requires it.
|
| 312 |
+
num_training_steps (`int``, *optional*):
|
| 313 |
+
The number of training steps to do. This is not required by all schedulers (hence the argument being
|
| 314 |
+
optional), the function will raise an error if it's unset and the scheduler type requires it.
|
| 315 |
+
num_cycles (`int`, *optional*):
|
| 316 |
+
The number of hard restarts used in `COSINE_WITH_RESTARTS` scheduler.
|
| 317 |
+
power (`float`, *optional*, defaults to 1.0):
|
| 318 |
+
Power factor. See `POLYNOMIAL` scheduler
|
| 319 |
+
last_epoch (`int`, *optional*, defaults to -1):
|
| 320 |
+
The index of the last epoch when resuming training.
|
| 321 |
+
"""
|
| 322 |
+
name = SchedulerType(name)
|
| 323 |
+
schedule_func = TYPE_TO_SCHEDULER_FUNCTION[name]
|
| 324 |
+
if name == SchedulerType.CONSTANT:
|
| 325 |
+
return schedule_func(optimizer, last_epoch=last_epoch)
|
| 326 |
+
|
| 327 |
+
if name == SchedulerType.PIECEWISE_CONSTANT:
|
| 328 |
+
return schedule_func(optimizer, step_rules=step_rules, last_epoch=last_epoch)
|
| 329 |
+
|
| 330 |
+
# All other schedulers require `num_warmup_steps`
|
| 331 |
+
if num_warmup_steps is None:
|
| 332 |
+
raise ValueError(f"{name} requires `num_warmup_steps`, please provide that argument.")
|
| 333 |
+
|
| 334 |
+
if name == SchedulerType.CONSTANT_WITH_WARMUP:
|
| 335 |
+
return schedule_func(optimizer, num_warmup_steps=num_warmup_steps, last_epoch=last_epoch)
|
| 336 |
+
|
| 337 |
+
# All other schedulers require `num_training_steps`
|
| 338 |
+
if num_training_steps is None:
|
| 339 |
+
raise ValueError(f"{name} requires `num_training_steps`, please provide that argument.")
|
| 340 |
+
|
| 341 |
+
if name == SchedulerType.COSINE_WITH_RESTARTS:
|
| 342 |
+
return schedule_func(
|
| 343 |
+
optimizer,
|
| 344 |
+
num_warmup_steps=num_warmup_steps,
|
| 345 |
+
num_training_steps=num_training_steps,
|
| 346 |
+
num_cycles=num_cycles,
|
| 347 |
+
last_epoch=last_epoch,
|
| 348 |
+
)
|
| 349 |
+
|
| 350 |
+
if name == SchedulerType.POLYNOMIAL:
|
| 351 |
+
return schedule_func(
|
| 352 |
+
optimizer,
|
| 353 |
+
num_warmup_steps=num_warmup_steps,
|
| 354 |
+
num_training_steps=num_training_steps,
|
| 355 |
+
power=power,
|
| 356 |
+
last_epoch=last_epoch,
|
| 357 |
+
)
|
| 358 |
+
|
| 359 |
+
return schedule_func(
|
| 360 |
+
optimizer, num_warmup_steps=num_warmup_steps, num_training_steps=num_training_steps, last_epoch=last_epoch
|
| 361 |
+
)
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__init__.py
ADDED
|
@@ -0,0 +1,860 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import TYPE_CHECKING
|
| 2 |
+
|
| 3 |
+
from ..utils import (
|
| 4 |
+
DIFFUSERS_SLOW_IMPORT,
|
| 5 |
+
OptionalDependencyNotAvailable,
|
| 6 |
+
_LazyModule,
|
| 7 |
+
get_objects_from_module,
|
| 8 |
+
is_flax_available,
|
| 9 |
+
is_k_diffusion_available,
|
| 10 |
+
is_librosa_available,
|
| 11 |
+
is_note_seq_available,
|
| 12 |
+
is_onnx_available,
|
| 13 |
+
is_opencv_available,
|
| 14 |
+
is_sentencepiece_available,
|
| 15 |
+
is_torch_available,
|
| 16 |
+
is_torch_npu_available,
|
| 17 |
+
is_transformers_available,
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
# These modules contain pipelines from multiple libraries/frameworks
|
| 22 |
+
_dummy_objects = {}
|
| 23 |
+
_import_structure = {
|
| 24 |
+
"controlnet": [],
|
| 25 |
+
"controlnet_hunyuandit": [],
|
| 26 |
+
"controlnet_sd3": [],
|
| 27 |
+
"controlnet_xs": [],
|
| 28 |
+
"deprecated": [],
|
| 29 |
+
"latent_diffusion": [],
|
| 30 |
+
"ledits_pp": [],
|
| 31 |
+
"marigold": [],
|
| 32 |
+
"pag": [],
|
| 33 |
+
"stable_diffusion": [],
|
| 34 |
+
"stable_diffusion_xl": [],
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
try:
|
| 38 |
+
if not is_torch_available():
|
| 39 |
+
raise OptionalDependencyNotAvailable()
|
| 40 |
+
except OptionalDependencyNotAvailable:
|
| 41 |
+
from ..utils import dummy_pt_objects # noqa F403
|
| 42 |
+
|
| 43 |
+
_dummy_objects.update(get_objects_from_module(dummy_pt_objects))
|
| 44 |
+
else:
|
| 45 |
+
_import_structure["auto_pipeline"] = [
|
| 46 |
+
"AutoPipelineForImage2Image",
|
| 47 |
+
"AutoPipelineForInpainting",
|
| 48 |
+
"AutoPipelineForText2Image",
|
| 49 |
+
]
|
| 50 |
+
_import_structure["consistency_models"] = ["ConsistencyModelPipeline"]
|
| 51 |
+
_import_structure["dance_diffusion"] = ["DanceDiffusionPipeline"]
|
| 52 |
+
_import_structure["ddim"] = ["DDIMPipeline"]
|
| 53 |
+
_import_structure["ddpm"] = ["DDPMPipeline"]
|
| 54 |
+
_import_structure["dit"] = ["DiTPipeline"]
|
| 55 |
+
_import_structure["latent_diffusion"].extend(["LDMSuperResolutionPipeline"])
|
| 56 |
+
_import_structure["pipeline_utils"] = [
|
| 57 |
+
"AudioPipelineOutput",
|
| 58 |
+
"DiffusionPipeline",
|
| 59 |
+
"StableDiffusionMixin",
|
| 60 |
+
"ImagePipelineOutput",
|
| 61 |
+
]
|
| 62 |
+
_import_structure["deprecated"].extend(
|
| 63 |
+
[
|
| 64 |
+
"PNDMPipeline",
|
| 65 |
+
"LDMPipeline",
|
| 66 |
+
"RePaintPipeline",
|
| 67 |
+
"ScoreSdeVePipeline",
|
| 68 |
+
"KarrasVePipeline",
|
| 69 |
+
]
|
| 70 |
+
)
|
| 71 |
+
try:
|
| 72 |
+
if not (is_torch_available() and is_librosa_available()):
|
| 73 |
+
raise OptionalDependencyNotAvailable()
|
| 74 |
+
except OptionalDependencyNotAvailable:
|
| 75 |
+
from ..utils import dummy_torch_and_librosa_objects # noqa F403
|
| 76 |
+
|
| 77 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_librosa_objects))
|
| 78 |
+
else:
|
| 79 |
+
_import_structure["deprecated"].extend(["AudioDiffusionPipeline", "Mel"])
|
| 80 |
+
|
| 81 |
+
try:
|
| 82 |
+
if not (is_transformers_available() and is_torch_available() and is_note_seq_available()):
|
| 83 |
+
raise OptionalDependencyNotAvailable()
|
| 84 |
+
except OptionalDependencyNotAvailable:
|
| 85 |
+
from ..utils import dummy_transformers_and_torch_and_note_seq_objects # noqa F403
|
| 86 |
+
|
| 87 |
+
_dummy_objects.update(get_objects_from_module(dummy_transformers_and_torch_and_note_seq_objects))
|
| 88 |
+
else:
|
| 89 |
+
_import_structure["deprecated"].extend(
|
| 90 |
+
[
|
| 91 |
+
"MidiProcessor",
|
| 92 |
+
"SpectrogramDiffusionPipeline",
|
| 93 |
+
]
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
try:
|
| 97 |
+
if not (is_torch_available() and is_transformers_available()):
|
| 98 |
+
raise OptionalDependencyNotAvailable()
|
| 99 |
+
except OptionalDependencyNotAvailable:
|
| 100 |
+
from ..utils import dummy_torch_and_transformers_objects # noqa F403
|
| 101 |
+
|
| 102 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_objects))
|
| 103 |
+
else:
|
| 104 |
+
_import_structure["deprecated"].extend(
|
| 105 |
+
[
|
| 106 |
+
"VQDiffusionPipeline",
|
| 107 |
+
"AltDiffusionPipeline",
|
| 108 |
+
"AltDiffusionImg2ImgPipeline",
|
| 109 |
+
"CycleDiffusionPipeline",
|
| 110 |
+
"StableDiffusionInpaintPipelineLegacy",
|
| 111 |
+
"StableDiffusionPix2PixZeroPipeline",
|
| 112 |
+
"StableDiffusionParadigmsPipeline",
|
| 113 |
+
"StableDiffusionModelEditingPipeline",
|
| 114 |
+
"VersatileDiffusionDualGuidedPipeline",
|
| 115 |
+
"VersatileDiffusionImageVariationPipeline",
|
| 116 |
+
"VersatileDiffusionPipeline",
|
| 117 |
+
"VersatileDiffusionTextToImagePipeline",
|
| 118 |
+
]
|
| 119 |
+
)
|
| 120 |
+
_import_structure["allegro"] = ["AllegroPipeline"]
|
| 121 |
+
_import_structure["amused"] = ["AmusedImg2ImgPipeline", "AmusedInpaintPipeline", "AmusedPipeline"]
|
| 122 |
+
_import_structure["animatediff"] = [
|
| 123 |
+
"AnimateDiffPipeline",
|
| 124 |
+
"AnimateDiffControlNetPipeline",
|
| 125 |
+
"AnimateDiffSDXLPipeline",
|
| 126 |
+
"AnimateDiffSparseControlNetPipeline",
|
| 127 |
+
"AnimateDiffVideoToVideoPipeline",
|
| 128 |
+
"AnimateDiffVideoToVideoControlNetPipeline",
|
| 129 |
+
]
|
| 130 |
+
_import_structure["flux"] = [
|
| 131 |
+
"FluxControlPipeline",
|
| 132 |
+
"FluxControlInpaintPipeline",
|
| 133 |
+
"FluxControlImg2ImgPipeline",
|
| 134 |
+
"FluxControlNetPipeline",
|
| 135 |
+
"FluxControlNetImg2ImgPipeline",
|
| 136 |
+
"FluxControlNetInpaintPipeline",
|
| 137 |
+
"FluxImg2ImgPipeline",
|
| 138 |
+
"FluxInpaintPipeline",
|
| 139 |
+
"FluxPipeline",
|
| 140 |
+
"FluxFillPipeline",
|
| 141 |
+
"FluxPriorReduxPipeline",
|
| 142 |
+
"ReduxImageEncoder",
|
| 143 |
+
]
|
| 144 |
+
_import_structure["audioldm"] = ["AudioLDMPipeline"]
|
| 145 |
+
_import_structure["audioldm2"] = [
|
| 146 |
+
"AudioLDM2Pipeline",
|
| 147 |
+
"AudioLDM2ProjectionModel",
|
| 148 |
+
"AudioLDM2UNet2DConditionModel",
|
| 149 |
+
]
|
| 150 |
+
_import_structure["blip_diffusion"] = ["BlipDiffusionPipeline"]
|
| 151 |
+
_import_structure["chroma"] = ["ChromaPipeline", "ChromaImg2ImgPipeline"]
|
| 152 |
+
_import_structure["cogvideo"] = [
|
| 153 |
+
"CogVideoXPipeline",
|
| 154 |
+
"CogVideoXImageToVideoPipeline",
|
| 155 |
+
"CogVideoXVideoToVideoPipeline",
|
| 156 |
+
"CogVideoXFunControlPipeline",
|
| 157 |
+
]
|
| 158 |
+
_import_structure["cogview3"] = ["CogView3PlusPipeline"]
|
| 159 |
+
_import_structure["cogview4"] = ["CogView4Pipeline", "CogView4ControlPipeline"]
|
| 160 |
+
_import_structure["consisid"] = ["ConsisIDPipeline"]
|
| 161 |
+
_import_structure["cosmos"] = [
|
| 162 |
+
"Cosmos2TextToImagePipeline",
|
| 163 |
+
"CosmosTextToWorldPipeline",
|
| 164 |
+
"CosmosVideoToWorldPipeline",
|
| 165 |
+
"Cosmos2VideoToWorldPipeline",
|
| 166 |
+
]
|
| 167 |
+
_import_structure["controlnet"].extend(
|
| 168 |
+
[
|
| 169 |
+
"BlipDiffusionControlNetPipeline",
|
| 170 |
+
"StableDiffusionControlNetImg2ImgPipeline",
|
| 171 |
+
"StableDiffusionControlNetInpaintPipeline",
|
| 172 |
+
"StableDiffusionControlNetPipeline",
|
| 173 |
+
"StableDiffusionXLControlNetImg2ImgPipeline",
|
| 174 |
+
"StableDiffusionXLControlNetInpaintPipeline",
|
| 175 |
+
"StableDiffusionXLControlNetPipeline",
|
| 176 |
+
"StableDiffusionXLControlNetUnionPipeline",
|
| 177 |
+
"StableDiffusionXLControlNetUnionInpaintPipeline",
|
| 178 |
+
"StableDiffusionXLControlNetUnionImg2ImgPipeline",
|
| 179 |
+
]
|
| 180 |
+
)
|
| 181 |
+
_import_structure["pag"].extend(
|
| 182 |
+
[
|
| 183 |
+
"StableDiffusionControlNetPAGInpaintPipeline",
|
| 184 |
+
"AnimateDiffPAGPipeline",
|
| 185 |
+
"KolorsPAGPipeline",
|
| 186 |
+
"HunyuanDiTPAGPipeline",
|
| 187 |
+
"StableDiffusion3PAGPipeline",
|
| 188 |
+
"StableDiffusion3PAGImg2ImgPipeline",
|
| 189 |
+
"StableDiffusionPAGPipeline",
|
| 190 |
+
"StableDiffusionPAGImg2ImgPipeline",
|
| 191 |
+
"StableDiffusionPAGInpaintPipeline",
|
| 192 |
+
"StableDiffusionControlNetPAGPipeline",
|
| 193 |
+
"StableDiffusionXLPAGPipeline",
|
| 194 |
+
"StableDiffusionXLPAGInpaintPipeline",
|
| 195 |
+
"StableDiffusionXLControlNetPAGImg2ImgPipeline",
|
| 196 |
+
"StableDiffusionXLControlNetPAGPipeline",
|
| 197 |
+
"StableDiffusionXLPAGImg2ImgPipeline",
|
| 198 |
+
"PixArtSigmaPAGPipeline",
|
| 199 |
+
"SanaPAGPipeline",
|
| 200 |
+
]
|
| 201 |
+
)
|
| 202 |
+
_import_structure["controlnet_xs"].extend(
|
| 203 |
+
[
|
| 204 |
+
"StableDiffusionControlNetXSPipeline",
|
| 205 |
+
"StableDiffusionXLControlNetXSPipeline",
|
| 206 |
+
]
|
| 207 |
+
)
|
| 208 |
+
_import_structure["controlnet_hunyuandit"].extend(
|
| 209 |
+
[
|
| 210 |
+
"HunyuanDiTControlNetPipeline",
|
| 211 |
+
]
|
| 212 |
+
)
|
| 213 |
+
_import_structure["controlnet_sd3"].extend(
|
| 214 |
+
[
|
| 215 |
+
"StableDiffusion3ControlNetPipeline",
|
| 216 |
+
"StableDiffusion3ControlNetInpaintingPipeline",
|
| 217 |
+
]
|
| 218 |
+
)
|
| 219 |
+
_import_structure["deepfloyd_if"] = [
|
| 220 |
+
"IFImg2ImgPipeline",
|
| 221 |
+
"IFImg2ImgSuperResolutionPipeline",
|
| 222 |
+
"IFInpaintingPipeline",
|
| 223 |
+
"IFInpaintingSuperResolutionPipeline",
|
| 224 |
+
"IFPipeline",
|
| 225 |
+
"IFSuperResolutionPipeline",
|
| 226 |
+
]
|
| 227 |
+
_import_structure["easyanimate"] = [
|
| 228 |
+
"EasyAnimatePipeline",
|
| 229 |
+
"EasyAnimateInpaintPipeline",
|
| 230 |
+
"EasyAnimateControlPipeline",
|
| 231 |
+
]
|
| 232 |
+
_import_structure["hidream_image"] = ["HiDreamImagePipeline"]
|
| 233 |
+
_import_structure["hunyuandit"] = ["HunyuanDiTPipeline"]
|
| 234 |
+
_import_structure["hunyuan_video"] = [
|
| 235 |
+
"HunyuanVideoPipeline",
|
| 236 |
+
"HunyuanSkyreelsImageToVideoPipeline",
|
| 237 |
+
"HunyuanVideoImageToVideoPipeline",
|
| 238 |
+
"HunyuanVideoFramepackPipeline",
|
| 239 |
+
]
|
| 240 |
+
_import_structure["kandinsky"] = [
|
| 241 |
+
"KandinskyCombinedPipeline",
|
| 242 |
+
"KandinskyImg2ImgCombinedPipeline",
|
| 243 |
+
"KandinskyImg2ImgPipeline",
|
| 244 |
+
"KandinskyInpaintCombinedPipeline",
|
| 245 |
+
"KandinskyInpaintPipeline",
|
| 246 |
+
"KandinskyPipeline",
|
| 247 |
+
"KandinskyPriorPipeline",
|
| 248 |
+
]
|
| 249 |
+
_import_structure["kandinsky2_2"] = [
|
| 250 |
+
"KandinskyV22CombinedPipeline",
|
| 251 |
+
"KandinskyV22ControlnetImg2ImgPipeline",
|
| 252 |
+
"KandinskyV22ControlnetPipeline",
|
| 253 |
+
"KandinskyV22Img2ImgCombinedPipeline",
|
| 254 |
+
"KandinskyV22Img2ImgPipeline",
|
| 255 |
+
"KandinskyV22InpaintCombinedPipeline",
|
| 256 |
+
"KandinskyV22InpaintPipeline",
|
| 257 |
+
"KandinskyV22Pipeline",
|
| 258 |
+
"KandinskyV22PriorEmb2EmbPipeline",
|
| 259 |
+
"KandinskyV22PriorPipeline",
|
| 260 |
+
]
|
| 261 |
+
_import_structure["kandinsky3"] = [
|
| 262 |
+
"Kandinsky3Img2ImgPipeline",
|
| 263 |
+
"Kandinsky3Pipeline",
|
| 264 |
+
]
|
| 265 |
+
_import_structure["latent_consistency_models"] = [
|
| 266 |
+
"LatentConsistencyModelImg2ImgPipeline",
|
| 267 |
+
"LatentConsistencyModelPipeline",
|
| 268 |
+
]
|
| 269 |
+
_import_structure["latent_diffusion"].extend(["LDMTextToImagePipeline"])
|
| 270 |
+
_import_structure["ledits_pp"].extend(
|
| 271 |
+
[
|
| 272 |
+
"LEditsPPPipelineStableDiffusion",
|
| 273 |
+
"LEditsPPPipelineStableDiffusionXL",
|
| 274 |
+
]
|
| 275 |
+
)
|
| 276 |
+
_import_structure["latte"] = ["LattePipeline"]
|
| 277 |
+
_import_structure["ltx"] = [
|
| 278 |
+
"LTXPipeline",
|
| 279 |
+
"LTXImageToVideoPipeline",
|
| 280 |
+
"LTXConditionPipeline",
|
| 281 |
+
"LTXLatentUpsamplePipeline",
|
| 282 |
+
]
|
| 283 |
+
_import_structure["lumina"] = ["LuminaPipeline", "LuminaText2ImgPipeline"]
|
| 284 |
+
_import_structure["lumina2"] = ["Lumina2Pipeline", "Lumina2Text2ImgPipeline"]
|
| 285 |
+
_import_structure["marigold"].extend(
|
| 286 |
+
[
|
| 287 |
+
"MarigoldDepthPipeline",
|
| 288 |
+
"MarigoldIntrinsicsPipeline",
|
| 289 |
+
"MarigoldNormalsPipeline",
|
| 290 |
+
]
|
| 291 |
+
)
|
| 292 |
+
_import_structure["mochi"] = ["MochiPipeline"]
|
| 293 |
+
_import_structure["musicldm"] = ["MusicLDMPipeline"]
|
| 294 |
+
_import_structure["omnigen"] = ["OmniGenPipeline"]
|
| 295 |
+
_import_structure["visualcloze"] = ["VisualClozePipeline", "VisualClozeGenerationPipeline"]
|
| 296 |
+
_import_structure["paint_by_example"] = ["PaintByExamplePipeline"]
|
| 297 |
+
_import_structure["pia"] = ["PIAPipeline"]
|
| 298 |
+
_import_structure["pixart_alpha"] = ["PixArtAlphaPipeline", "PixArtSigmaPipeline"]
|
| 299 |
+
_import_structure["sana"] = [
|
| 300 |
+
"SanaPipeline",
|
| 301 |
+
"SanaSprintPipeline",
|
| 302 |
+
"SanaControlNetPipeline",
|
| 303 |
+
"SanaSprintImg2ImgPipeline",
|
| 304 |
+
]
|
| 305 |
+
_import_structure["semantic_stable_diffusion"] = ["SemanticStableDiffusionPipeline"]
|
| 306 |
+
_import_structure["shap_e"] = ["ShapEImg2ImgPipeline", "ShapEPipeline"]
|
| 307 |
+
_import_structure["stable_audio"] = [
|
| 308 |
+
"StableAudioProjectionModel",
|
| 309 |
+
"StableAudioPipeline",
|
| 310 |
+
]
|
| 311 |
+
_import_structure["stable_cascade"] = [
|
| 312 |
+
"StableCascadeCombinedPipeline",
|
| 313 |
+
"StableCascadeDecoderPipeline",
|
| 314 |
+
"StableCascadePriorPipeline",
|
| 315 |
+
]
|
| 316 |
+
_import_structure["stable_diffusion"].extend(
|
| 317 |
+
[
|
| 318 |
+
"CLIPImageProjection",
|
| 319 |
+
"StableDiffusionDepth2ImgPipeline",
|
| 320 |
+
"StableDiffusionImageVariationPipeline",
|
| 321 |
+
"StableDiffusionImg2ImgPipeline",
|
| 322 |
+
"StableDiffusionInpaintPipeline",
|
| 323 |
+
"StableDiffusionInstructPix2PixPipeline",
|
| 324 |
+
"StableDiffusionLatentUpscalePipeline",
|
| 325 |
+
"StableDiffusionPipeline",
|
| 326 |
+
"StableDiffusionUpscalePipeline",
|
| 327 |
+
"StableUnCLIPImg2ImgPipeline",
|
| 328 |
+
"StableUnCLIPPipeline",
|
| 329 |
+
"StableDiffusionLDM3DPipeline",
|
| 330 |
+
]
|
| 331 |
+
)
|
| 332 |
+
_import_structure["aura_flow"] = ["AuraFlowPipeline"]
|
| 333 |
+
_import_structure["stable_diffusion_3"] = [
|
| 334 |
+
"StableDiffusion3Pipeline",
|
| 335 |
+
"StableDiffusion3Img2ImgPipeline",
|
| 336 |
+
"StableDiffusion3InpaintPipeline",
|
| 337 |
+
]
|
| 338 |
+
_import_structure["stable_diffusion_attend_and_excite"] = ["StableDiffusionAttendAndExcitePipeline"]
|
| 339 |
+
_import_structure["stable_diffusion_safe"] = ["StableDiffusionPipelineSafe"]
|
| 340 |
+
_import_structure["stable_diffusion_sag"] = ["StableDiffusionSAGPipeline"]
|
| 341 |
+
_import_structure["stable_diffusion_gligen"] = [
|
| 342 |
+
"StableDiffusionGLIGENPipeline",
|
| 343 |
+
"StableDiffusionGLIGENTextImagePipeline",
|
| 344 |
+
]
|
| 345 |
+
_import_structure["stable_video_diffusion"] = ["StableVideoDiffusionPipeline"]
|
| 346 |
+
_import_structure["stable_diffusion_xl"].extend(
|
| 347 |
+
[
|
| 348 |
+
"StableDiffusionXLImg2ImgPipeline",
|
| 349 |
+
"StableDiffusionXLInpaintPipeline",
|
| 350 |
+
"StableDiffusionXLInstructPix2PixPipeline",
|
| 351 |
+
"StableDiffusionXLPipeline",
|
| 352 |
+
]
|
| 353 |
+
)
|
| 354 |
+
_import_structure["stable_diffusion_diffedit"] = ["StableDiffusionDiffEditPipeline"]
|
| 355 |
+
_import_structure["stable_diffusion_ldm3d"] = ["StableDiffusionLDM3DPipeline"]
|
| 356 |
+
_import_structure["stable_diffusion_panorama"] = ["StableDiffusionPanoramaPipeline"]
|
| 357 |
+
_import_structure["t2i_adapter"] = [
|
| 358 |
+
"StableDiffusionAdapterPipeline",
|
| 359 |
+
"StableDiffusionXLAdapterPipeline",
|
| 360 |
+
]
|
| 361 |
+
_import_structure["text_to_video_synthesis"] = [
|
| 362 |
+
"TextToVideoSDPipeline",
|
| 363 |
+
"TextToVideoZeroPipeline",
|
| 364 |
+
"TextToVideoZeroSDXLPipeline",
|
| 365 |
+
"VideoToVideoSDPipeline",
|
| 366 |
+
]
|
| 367 |
+
_import_structure["i2vgen_xl"] = ["I2VGenXLPipeline"]
|
| 368 |
+
_import_structure["unclip"] = ["UnCLIPImageVariationPipeline", "UnCLIPPipeline"]
|
| 369 |
+
_import_structure["unidiffuser"] = [
|
| 370 |
+
"ImageTextPipelineOutput",
|
| 371 |
+
"UniDiffuserModel",
|
| 372 |
+
"UniDiffuserPipeline",
|
| 373 |
+
"UniDiffuserTextDecoder",
|
| 374 |
+
]
|
| 375 |
+
_import_structure["wuerstchen"] = [
|
| 376 |
+
"WuerstchenCombinedPipeline",
|
| 377 |
+
"WuerstchenDecoderPipeline",
|
| 378 |
+
"WuerstchenPriorPipeline",
|
| 379 |
+
]
|
| 380 |
+
_import_structure["wan"] = ["WanPipeline", "WanImageToVideoPipeline", "WanVideoToVideoPipeline", "WanVACEPipeline"]
|
| 381 |
+
try:
|
| 382 |
+
if not is_onnx_available():
|
| 383 |
+
raise OptionalDependencyNotAvailable()
|
| 384 |
+
except OptionalDependencyNotAvailable:
|
| 385 |
+
from ..utils import dummy_onnx_objects # noqa F403
|
| 386 |
+
|
| 387 |
+
_dummy_objects.update(get_objects_from_module(dummy_onnx_objects))
|
| 388 |
+
else:
|
| 389 |
+
_import_structure["onnx_utils"] = ["OnnxRuntimeModel"]
|
| 390 |
+
try:
|
| 391 |
+
if not (is_torch_available() and is_transformers_available() and is_onnx_available()):
|
| 392 |
+
raise OptionalDependencyNotAvailable()
|
| 393 |
+
except OptionalDependencyNotAvailable:
|
| 394 |
+
from ..utils import dummy_torch_and_transformers_and_onnx_objects # noqa F403
|
| 395 |
+
|
| 396 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_and_onnx_objects))
|
| 397 |
+
else:
|
| 398 |
+
_import_structure["stable_diffusion"].extend(
|
| 399 |
+
[
|
| 400 |
+
"OnnxStableDiffusionImg2ImgPipeline",
|
| 401 |
+
"OnnxStableDiffusionInpaintPipeline",
|
| 402 |
+
"OnnxStableDiffusionPipeline",
|
| 403 |
+
"OnnxStableDiffusionUpscalePipeline",
|
| 404 |
+
"StableDiffusionOnnxPipeline",
|
| 405 |
+
]
|
| 406 |
+
)
|
| 407 |
+
|
| 408 |
+
try:
|
| 409 |
+
if not (is_torch_available() and is_transformers_available() and is_k_diffusion_available()):
|
| 410 |
+
raise OptionalDependencyNotAvailable()
|
| 411 |
+
except OptionalDependencyNotAvailable:
|
| 412 |
+
from ..utils import (
|
| 413 |
+
dummy_torch_and_transformers_and_k_diffusion_objects,
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_and_k_diffusion_objects))
|
| 417 |
+
else:
|
| 418 |
+
_import_structure["stable_diffusion_k_diffusion"] = [
|
| 419 |
+
"StableDiffusionKDiffusionPipeline",
|
| 420 |
+
"StableDiffusionXLKDiffusionPipeline",
|
| 421 |
+
]
|
| 422 |
+
|
| 423 |
+
try:
|
| 424 |
+
if not (is_torch_available() and is_transformers_available() and is_sentencepiece_available()):
|
| 425 |
+
raise OptionalDependencyNotAvailable()
|
| 426 |
+
except OptionalDependencyNotAvailable:
|
| 427 |
+
from ..utils import (
|
| 428 |
+
dummy_torch_and_transformers_and_sentencepiece_objects,
|
| 429 |
+
)
|
| 430 |
+
|
| 431 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_and_sentencepiece_objects))
|
| 432 |
+
else:
|
| 433 |
+
_import_structure["kolors"] = [
|
| 434 |
+
"KolorsPipeline",
|
| 435 |
+
"KolorsImg2ImgPipeline",
|
| 436 |
+
]
|
| 437 |
+
|
| 438 |
+
try:
|
| 439 |
+
if not (is_torch_available() and is_transformers_available() and is_opencv_available()):
|
| 440 |
+
raise OptionalDependencyNotAvailable()
|
| 441 |
+
except OptionalDependencyNotAvailable:
|
| 442 |
+
from ..utils import (
|
| 443 |
+
dummy_torch_and_transformers_and_opencv_objects,
|
| 444 |
+
)
|
| 445 |
+
|
| 446 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_and_opencv_objects))
|
| 447 |
+
else:
|
| 448 |
+
_import_structure["consisid"] = ["ConsisIDPipeline"]
|
| 449 |
+
|
| 450 |
+
try:
|
| 451 |
+
if not is_flax_available():
|
| 452 |
+
raise OptionalDependencyNotAvailable()
|
| 453 |
+
except OptionalDependencyNotAvailable:
|
| 454 |
+
from ..utils import dummy_flax_objects # noqa F403
|
| 455 |
+
|
| 456 |
+
_dummy_objects.update(get_objects_from_module(dummy_flax_objects))
|
| 457 |
+
else:
|
| 458 |
+
_import_structure["pipeline_flax_utils"] = ["FlaxDiffusionPipeline"]
|
| 459 |
+
try:
|
| 460 |
+
if not (is_flax_available() and is_transformers_available()):
|
| 461 |
+
raise OptionalDependencyNotAvailable()
|
| 462 |
+
except OptionalDependencyNotAvailable:
|
| 463 |
+
from ..utils import dummy_flax_and_transformers_objects # noqa F403
|
| 464 |
+
|
| 465 |
+
_dummy_objects.update(get_objects_from_module(dummy_flax_and_transformers_objects))
|
| 466 |
+
else:
|
| 467 |
+
_import_structure["controlnet"].extend(["FlaxStableDiffusionControlNetPipeline"])
|
| 468 |
+
_import_structure["stable_diffusion"].extend(
|
| 469 |
+
[
|
| 470 |
+
"FlaxStableDiffusionImg2ImgPipeline",
|
| 471 |
+
"FlaxStableDiffusionInpaintPipeline",
|
| 472 |
+
"FlaxStableDiffusionPipeline",
|
| 473 |
+
]
|
| 474 |
+
)
|
| 475 |
+
_import_structure["stable_diffusion_xl"].extend(
|
| 476 |
+
[
|
| 477 |
+
"FlaxStableDiffusionXLPipeline",
|
| 478 |
+
]
|
| 479 |
+
)
|
| 480 |
+
|
| 481 |
+
if TYPE_CHECKING or DIFFUSERS_SLOW_IMPORT:
|
| 482 |
+
try:
|
| 483 |
+
if not is_torch_available():
|
| 484 |
+
raise OptionalDependencyNotAvailable()
|
| 485 |
+
except OptionalDependencyNotAvailable:
|
| 486 |
+
from ..utils.dummy_pt_objects import * # noqa F403
|
| 487 |
+
|
| 488 |
+
else:
|
| 489 |
+
from .auto_pipeline import (
|
| 490 |
+
AutoPipelineForImage2Image,
|
| 491 |
+
AutoPipelineForInpainting,
|
| 492 |
+
AutoPipelineForText2Image,
|
| 493 |
+
)
|
| 494 |
+
from .consistency_models import ConsistencyModelPipeline
|
| 495 |
+
from .dance_diffusion import DanceDiffusionPipeline
|
| 496 |
+
from .ddim import DDIMPipeline
|
| 497 |
+
from .ddpm import DDPMPipeline
|
| 498 |
+
from .deprecated import KarrasVePipeline, LDMPipeline, PNDMPipeline, RePaintPipeline, ScoreSdeVePipeline
|
| 499 |
+
from .dit import DiTPipeline
|
| 500 |
+
from .latent_diffusion import LDMSuperResolutionPipeline
|
| 501 |
+
from .pipeline_utils import (
|
| 502 |
+
AudioPipelineOutput,
|
| 503 |
+
DiffusionPipeline,
|
| 504 |
+
ImagePipelineOutput,
|
| 505 |
+
StableDiffusionMixin,
|
| 506 |
+
)
|
| 507 |
+
|
| 508 |
+
try:
|
| 509 |
+
if not (is_torch_available() and is_librosa_available()):
|
| 510 |
+
raise OptionalDependencyNotAvailable()
|
| 511 |
+
except OptionalDependencyNotAvailable:
|
| 512 |
+
from ..utils.dummy_torch_and_librosa_objects import *
|
| 513 |
+
else:
|
| 514 |
+
from .deprecated import AudioDiffusionPipeline, Mel
|
| 515 |
+
|
| 516 |
+
try:
|
| 517 |
+
if not (is_torch_available() and is_transformers_available()):
|
| 518 |
+
raise OptionalDependencyNotAvailable()
|
| 519 |
+
except OptionalDependencyNotAvailable:
|
| 520 |
+
from ..utils.dummy_torch_and_transformers_objects import *
|
| 521 |
+
else:
|
| 522 |
+
from .allegro import AllegroPipeline
|
| 523 |
+
from .amused import AmusedImg2ImgPipeline, AmusedInpaintPipeline, AmusedPipeline
|
| 524 |
+
from .animatediff import (
|
| 525 |
+
AnimateDiffControlNetPipeline,
|
| 526 |
+
AnimateDiffPipeline,
|
| 527 |
+
AnimateDiffSDXLPipeline,
|
| 528 |
+
AnimateDiffSparseControlNetPipeline,
|
| 529 |
+
AnimateDiffVideoToVideoControlNetPipeline,
|
| 530 |
+
AnimateDiffVideoToVideoPipeline,
|
| 531 |
+
)
|
| 532 |
+
from .audioldm import AudioLDMPipeline
|
| 533 |
+
from .audioldm2 import (
|
| 534 |
+
AudioLDM2Pipeline,
|
| 535 |
+
AudioLDM2ProjectionModel,
|
| 536 |
+
AudioLDM2UNet2DConditionModel,
|
| 537 |
+
)
|
| 538 |
+
from .aura_flow import AuraFlowPipeline
|
| 539 |
+
from .blip_diffusion import BlipDiffusionPipeline
|
| 540 |
+
from .chroma import ChromaImg2ImgPipeline, ChromaPipeline
|
| 541 |
+
from .cogvideo import (
|
| 542 |
+
CogVideoXFunControlPipeline,
|
| 543 |
+
CogVideoXImageToVideoPipeline,
|
| 544 |
+
CogVideoXPipeline,
|
| 545 |
+
CogVideoXVideoToVideoPipeline,
|
| 546 |
+
)
|
| 547 |
+
from .cogview3 import CogView3PlusPipeline
|
| 548 |
+
from .cogview4 import CogView4ControlPipeline, CogView4Pipeline
|
| 549 |
+
from .controlnet import (
|
| 550 |
+
BlipDiffusionControlNetPipeline,
|
| 551 |
+
StableDiffusionControlNetImg2ImgPipeline,
|
| 552 |
+
StableDiffusionControlNetInpaintPipeline,
|
| 553 |
+
StableDiffusionControlNetPipeline,
|
| 554 |
+
StableDiffusionXLControlNetImg2ImgPipeline,
|
| 555 |
+
StableDiffusionXLControlNetInpaintPipeline,
|
| 556 |
+
StableDiffusionXLControlNetPipeline,
|
| 557 |
+
StableDiffusionXLControlNetUnionImg2ImgPipeline,
|
| 558 |
+
StableDiffusionXLControlNetUnionInpaintPipeline,
|
| 559 |
+
StableDiffusionXLControlNetUnionPipeline,
|
| 560 |
+
)
|
| 561 |
+
from .controlnet_hunyuandit import (
|
| 562 |
+
HunyuanDiTControlNetPipeline,
|
| 563 |
+
)
|
| 564 |
+
from .controlnet_sd3 import StableDiffusion3ControlNetInpaintingPipeline, StableDiffusion3ControlNetPipeline
|
| 565 |
+
from .controlnet_xs import (
|
| 566 |
+
StableDiffusionControlNetXSPipeline,
|
| 567 |
+
StableDiffusionXLControlNetXSPipeline,
|
| 568 |
+
)
|
| 569 |
+
from .cosmos import (
|
| 570 |
+
Cosmos2TextToImagePipeline,
|
| 571 |
+
Cosmos2VideoToWorldPipeline,
|
| 572 |
+
CosmosTextToWorldPipeline,
|
| 573 |
+
CosmosVideoToWorldPipeline,
|
| 574 |
+
)
|
| 575 |
+
from .deepfloyd_if import (
|
| 576 |
+
IFImg2ImgPipeline,
|
| 577 |
+
IFImg2ImgSuperResolutionPipeline,
|
| 578 |
+
IFInpaintingPipeline,
|
| 579 |
+
IFInpaintingSuperResolutionPipeline,
|
| 580 |
+
IFPipeline,
|
| 581 |
+
IFSuperResolutionPipeline,
|
| 582 |
+
)
|
| 583 |
+
from .deprecated import (
|
| 584 |
+
AltDiffusionImg2ImgPipeline,
|
| 585 |
+
AltDiffusionPipeline,
|
| 586 |
+
CycleDiffusionPipeline,
|
| 587 |
+
StableDiffusionInpaintPipelineLegacy,
|
| 588 |
+
StableDiffusionModelEditingPipeline,
|
| 589 |
+
StableDiffusionParadigmsPipeline,
|
| 590 |
+
StableDiffusionPix2PixZeroPipeline,
|
| 591 |
+
VersatileDiffusionDualGuidedPipeline,
|
| 592 |
+
VersatileDiffusionImageVariationPipeline,
|
| 593 |
+
VersatileDiffusionPipeline,
|
| 594 |
+
VersatileDiffusionTextToImagePipeline,
|
| 595 |
+
VQDiffusionPipeline,
|
| 596 |
+
)
|
| 597 |
+
from .easyanimate import (
|
| 598 |
+
EasyAnimateControlPipeline,
|
| 599 |
+
EasyAnimateInpaintPipeline,
|
| 600 |
+
EasyAnimatePipeline,
|
| 601 |
+
)
|
| 602 |
+
from .flux import (
|
| 603 |
+
FluxControlImg2ImgPipeline,
|
| 604 |
+
FluxControlInpaintPipeline,
|
| 605 |
+
FluxControlNetImg2ImgPipeline,
|
| 606 |
+
FluxControlNetInpaintPipeline,
|
| 607 |
+
FluxControlNetPipeline,
|
| 608 |
+
FluxControlPipeline,
|
| 609 |
+
FluxFillPipeline,
|
| 610 |
+
FluxImg2ImgPipeline,
|
| 611 |
+
FluxInpaintPipeline,
|
| 612 |
+
FluxPipeline,
|
| 613 |
+
FluxPriorReduxPipeline,
|
| 614 |
+
ReduxImageEncoder,
|
| 615 |
+
)
|
| 616 |
+
from .hidream_image import HiDreamImagePipeline
|
| 617 |
+
from .hunyuan_video import (
|
| 618 |
+
HunyuanSkyreelsImageToVideoPipeline,
|
| 619 |
+
HunyuanVideoFramepackPipeline,
|
| 620 |
+
HunyuanVideoImageToVideoPipeline,
|
| 621 |
+
HunyuanVideoPipeline,
|
| 622 |
+
)
|
| 623 |
+
from .hunyuandit import HunyuanDiTPipeline
|
| 624 |
+
from .i2vgen_xl import I2VGenXLPipeline
|
| 625 |
+
from .kandinsky import (
|
| 626 |
+
KandinskyCombinedPipeline,
|
| 627 |
+
KandinskyImg2ImgCombinedPipeline,
|
| 628 |
+
KandinskyImg2ImgPipeline,
|
| 629 |
+
KandinskyInpaintCombinedPipeline,
|
| 630 |
+
KandinskyInpaintPipeline,
|
| 631 |
+
KandinskyPipeline,
|
| 632 |
+
KandinskyPriorPipeline,
|
| 633 |
+
)
|
| 634 |
+
from .kandinsky2_2 import (
|
| 635 |
+
KandinskyV22CombinedPipeline,
|
| 636 |
+
KandinskyV22ControlnetImg2ImgPipeline,
|
| 637 |
+
KandinskyV22ControlnetPipeline,
|
| 638 |
+
KandinskyV22Img2ImgCombinedPipeline,
|
| 639 |
+
KandinskyV22Img2ImgPipeline,
|
| 640 |
+
KandinskyV22InpaintCombinedPipeline,
|
| 641 |
+
KandinskyV22InpaintPipeline,
|
| 642 |
+
KandinskyV22Pipeline,
|
| 643 |
+
KandinskyV22PriorEmb2EmbPipeline,
|
| 644 |
+
KandinskyV22PriorPipeline,
|
| 645 |
+
)
|
| 646 |
+
from .kandinsky3 import (
|
| 647 |
+
Kandinsky3Img2ImgPipeline,
|
| 648 |
+
Kandinsky3Pipeline,
|
| 649 |
+
)
|
| 650 |
+
from .latent_consistency_models import (
|
| 651 |
+
LatentConsistencyModelImg2ImgPipeline,
|
| 652 |
+
LatentConsistencyModelPipeline,
|
| 653 |
+
)
|
| 654 |
+
from .latent_diffusion import LDMTextToImagePipeline
|
| 655 |
+
from .latte import LattePipeline
|
| 656 |
+
from .ledits_pp import (
|
| 657 |
+
LEditsPPDiffusionPipelineOutput,
|
| 658 |
+
LEditsPPInversionPipelineOutput,
|
| 659 |
+
LEditsPPPipelineStableDiffusion,
|
| 660 |
+
LEditsPPPipelineStableDiffusionXL,
|
| 661 |
+
)
|
| 662 |
+
from .ltx import LTXConditionPipeline, LTXImageToVideoPipeline, LTXLatentUpsamplePipeline, LTXPipeline
|
| 663 |
+
from .lumina import LuminaPipeline, LuminaText2ImgPipeline
|
| 664 |
+
from .lumina2 import Lumina2Pipeline, Lumina2Text2ImgPipeline
|
| 665 |
+
from .marigold import (
|
| 666 |
+
MarigoldDepthPipeline,
|
| 667 |
+
MarigoldIntrinsicsPipeline,
|
| 668 |
+
MarigoldNormalsPipeline,
|
| 669 |
+
)
|
| 670 |
+
from .mochi import MochiPipeline
|
| 671 |
+
from .musicldm import MusicLDMPipeline
|
| 672 |
+
from .omnigen import OmniGenPipeline
|
| 673 |
+
from .pag import (
|
| 674 |
+
AnimateDiffPAGPipeline,
|
| 675 |
+
HunyuanDiTPAGPipeline,
|
| 676 |
+
KolorsPAGPipeline,
|
| 677 |
+
PixArtSigmaPAGPipeline,
|
| 678 |
+
SanaPAGPipeline,
|
| 679 |
+
StableDiffusion3PAGImg2ImgPipeline,
|
| 680 |
+
StableDiffusion3PAGPipeline,
|
| 681 |
+
StableDiffusionControlNetPAGInpaintPipeline,
|
| 682 |
+
StableDiffusionControlNetPAGPipeline,
|
| 683 |
+
StableDiffusionPAGImg2ImgPipeline,
|
| 684 |
+
StableDiffusionPAGInpaintPipeline,
|
| 685 |
+
StableDiffusionPAGPipeline,
|
| 686 |
+
StableDiffusionXLControlNetPAGImg2ImgPipeline,
|
| 687 |
+
StableDiffusionXLControlNetPAGPipeline,
|
| 688 |
+
StableDiffusionXLPAGImg2ImgPipeline,
|
| 689 |
+
StableDiffusionXLPAGInpaintPipeline,
|
| 690 |
+
StableDiffusionXLPAGPipeline,
|
| 691 |
+
)
|
| 692 |
+
from .paint_by_example import PaintByExamplePipeline
|
| 693 |
+
from .pia import PIAPipeline
|
| 694 |
+
from .pixart_alpha import PixArtAlphaPipeline, PixArtSigmaPipeline
|
| 695 |
+
from .sana import SanaControlNetPipeline, SanaPipeline, SanaSprintImg2ImgPipeline, SanaSprintPipeline
|
| 696 |
+
from .semantic_stable_diffusion import SemanticStableDiffusionPipeline
|
| 697 |
+
from .shap_e import ShapEImg2ImgPipeline, ShapEPipeline
|
| 698 |
+
from .stable_audio import StableAudioPipeline, StableAudioProjectionModel
|
| 699 |
+
from .stable_cascade import (
|
| 700 |
+
StableCascadeCombinedPipeline,
|
| 701 |
+
StableCascadeDecoderPipeline,
|
| 702 |
+
StableCascadePriorPipeline,
|
| 703 |
+
)
|
| 704 |
+
from .stable_diffusion import (
|
| 705 |
+
CLIPImageProjection,
|
| 706 |
+
StableDiffusionDepth2ImgPipeline,
|
| 707 |
+
StableDiffusionImageVariationPipeline,
|
| 708 |
+
StableDiffusionImg2ImgPipeline,
|
| 709 |
+
StableDiffusionInpaintPipeline,
|
| 710 |
+
StableDiffusionInstructPix2PixPipeline,
|
| 711 |
+
StableDiffusionLatentUpscalePipeline,
|
| 712 |
+
StableDiffusionPipeline,
|
| 713 |
+
StableDiffusionUpscalePipeline,
|
| 714 |
+
StableUnCLIPImg2ImgPipeline,
|
| 715 |
+
StableUnCLIPPipeline,
|
| 716 |
+
)
|
| 717 |
+
from .stable_diffusion_3 import (
|
| 718 |
+
StableDiffusion3Img2ImgPipeline,
|
| 719 |
+
StableDiffusion3InpaintPipeline,
|
| 720 |
+
StableDiffusion3Pipeline,
|
| 721 |
+
)
|
| 722 |
+
from .stable_diffusion_attend_and_excite import StableDiffusionAttendAndExcitePipeline
|
| 723 |
+
from .stable_diffusion_diffedit import StableDiffusionDiffEditPipeline
|
| 724 |
+
from .stable_diffusion_gligen import StableDiffusionGLIGENPipeline, StableDiffusionGLIGENTextImagePipeline
|
| 725 |
+
from .stable_diffusion_ldm3d import StableDiffusionLDM3DPipeline
|
| 726 |
+
from .stable_diffusion_panorama import StableDiffusionPanoramaPipeline
|
| 727 |
+
from .stable_diffusion_safe import StableDiffusionPipelineSafe
|
| 728 |
+
from .stable_diffusion_sag import StableDiffusionSAGPipeline
|
| 729 |
+
from .stable_diffusion_xl import (
|
| 730 |
+
StableDiffusionXLImg2ImgPipeline,
|
| 731 |
+
StableDiffusionXLInpaintPipeline,
|
| 732 |
+
StableDiffusionXLInstructPix2PixPipeline,
|
| 733 |
+
StableDiffusionXLPipeline,
|
| 734 |
+
)
|
| 735 |
+
from .stable_video_diffusion import StableVideoDiffusionPipeline
|
| 736 |
+
from .t2i_adapter import (
|
| 737 |
+
StableDiffusionAdapterPipeline,
|
| 738 |
+
StableDiffusionXLAdapterPipeline,
|
| 739 |
+
)
|
| 740 |
+
from .text_to_video_synthesis import (
|
| 741 |
+
TextToVideoSDPipeline,
|
| 742 |
+
TextToVideoZeroPipeline,
|
| 743 |
+
TextToVideoZeroSDXLPipeline,
|
| 744 |
+
VideoToVideoSDPipeline,
|
| 745 |
+
)
|
| 746 |
+
from .unclip import UnCLIPImageVariationPipeline, UnCLIPPipeline
|
| 747 |
+
from .unidiffuser import (
|
| 748 |
+
ImageTextPipelineOutput,
|
| 749 |
+
UniDiffuserModel,
|
| 750 |
+
UniDiffuserPipeline,
|
| 751 |
+
UniDiffuserTextDecoder,
|
| 752 |
+
)
|
| 753 |
+
from .visualcloze import VisualClozeGenerationPipeline, VisualClozePipeline
|
| 754 |
+
from .wan import WanImageToVideoPipeline, WanPipeline, WanVACEPipeline, WanVideoToVideoPipeline
|
| 755 |
+
from .wuerstchen import (
|
| 756 |
+
WuerstchenCombinedPipeline,
|
| 757 |
+
WuerstchenDecoderPipeline,
|
| 758 |
+
WuerstchenPriorPipeline,
|
| 759 |
+
)
|
| 760 |
+
|
| 761 |
+
try:
|
| 762 |
+
if not is_onnx_available():
|
| 763 |
+
raise OptionalDependencyNotAvailable()
|
| 764 |
+
except OptionalDependencyNotAvailable:
|
| 765 |
+
from ..utils.dummy_onnx_objects import * # noqa F403
|
| 766 |
+
|
| 767 |
+
else:
|
| 768 |
+
from .onnx_utils import OnnxRuntimeModel
|
| 769 |
+
|
| 770 |
+
try:
|
| 771 |
+
if not (is_torch_available() and is_transformers_available() and is_onnx_available()):
|
| 772 |
+
raise OptionalDependencyNotAvailable()
|
| 773 |
+
except OptionalDependencyNotAvailable:
|
| 774 |
+
from ..utils.dummy_torch_and_transformers_and_onnx_objects import *
|
| 775 |
+
else:
|
| 776 |
+
from .stable_diffusion import (
|
| 777 |
+
OnnxStableDiffusionImg2ImgPipeline,
|
| 778 |
+
OnnxStableDiffusionInpaintPipeline,
|
| 779 |
+
OnnxStableDiffusionPipeline,
|
| 780 |
+
OnnxStableDiffusionUpscalePipeline,
|
| 781 |
+
StableDiffusionOnnxPipeline,
|
| 782 |
+
)
|
| 783 |
+
|
| 784 |
+
try:
|
| 785 |
+
if not (is_torch_available() and is_transformers_available() and is_k_diffusion_available()):
|
| 786 |
+
raise OptionalDependencyNotAvailable()
|
| 787 |
+
except OptionalDependencyNotAvailable:
|
| 788 |
+
from ..utils.dummy_torch_and_transformers_and_k_diffusion_objects import *
|
| 789 |
+
else:
|
| 790 |
+
from .stable_diffusion_k_diffusion import (
|
| 791 |
+
StableDiffusionKDiffusionPipeline,
|
| 792 |
+
StableDiffusionXLKDiffusionPipeline,
|
| 793 |
+
)
|
| 794 |
+
|
| 795 |
+
try:
|
| 796 |
+
if not (is_torch_available() and is_transformers_available() and is_sentencepiece_available()):
|
| 797 |
+
raise OptionalDependencyNotAvailable()
|
| 798 |
+
except OptionalDependencyNotAvailable:
|
| 799 |
+
from ..utils.dummy_torch_and_transformers_and_sentencepiece_objects import *
|
| 800 |
+
else:
|
| 801 |
+
from .kolors import (
|
| 802 |
+
KolorsImg2ImgPipeline,
|
| 803 |
+
KolorsPipeline,
|
| 804 |
+
)
|
| 805 |
+
|
| 806 |
+
try:
|
| 807 |
+
if not (is_torch_available() and is_transformers_available() and is_opencv_available()):
|
| 808 |
+
raise OptionalDependencyNotAvailable()
|
| 809 |
+
except OptionalDependencyNotAvailable:
|
| 810 |
+
from ..utils.dummy_torch_and_transformers_and_opencv_objects import *
|
| 811 |
+
else:
|
| 812 |
+
from .consisid import ConsisIDPipeline
|
| 813 |
+
|
| 814 |
+
try:
|
| 815 |
+
if not is_flax_available():
|
| 816 |
+
raise OptionalDependencyNotAvailable()
|
| 817 |
+
except OptionalDependencyNotAvailable:
|
| 818 |
+
from ..utils.dummy_flax_objects import * # noqa F403
|
| 819 |
+
else:
|
| 820 |
+
from .pipeline_flax_utils import FlaxDiffusionPipeline
|
| 821 |
+
|
| 822 |
+
try:
|
| 823 |
+
if not (is_flax_available() and is_transformers_available()):
|
| 824 |
+
raise OptionalDependencyNotAvailable()
|
| 825 |
+
except OptionalDependencyNotAvailable:
|
| 826 |
+
from ..utils.dummy_flax_and_transformers_objects import *
|
| 827 |
+
else:
|
| 828 |
+
from .controlnet import FlaxStableDiffusionControlNetPipeline
|
| 829 |
+
from .stable_diffusion import (
|
| 830 |
+
FlaxStableDiffusionImg2ImgPipeline,
|
| 831 |
+
FlaxStableDiffusionInpaintPipeline,
|
| 832 |
+
FlaxStableDiffusionPipeline,
|
| 833 |
+
)
|
| 834 |
+
from .stable_diffusion_xl import (
|
| 835 |
+
FlaxStableDiffusionXLPipeline,
|
| 836 |
+
)
|
| 837 |
+
|
| 838 |
+
try:
|
| 839 |
+
if not (is_transformers_available() and is_torch_available() and is_note_seq_available()):
|
| 840 |
+
raise OptionalDependencyNotAvailable()
|
| 841 |
+
except OptionalDependencyNotAvailable:
|
| 842 |
+
from ..utils.dummy_transformers_and_torch_and_note_seq_objects import * # noqa F403
|
| 843 |
+
|
| 844 |
+
else:
|
| 845 |
+
from .deprecated import (
|
| 846 |
+
MidiProcessor,
|
| 847 |
+
SpectrogramDiffusionPipeline,
|
| 848 |
+
)
|
| 849 |
+
|
| 850 |
+
else:
|
| 851 |
+
import sys
|
| 852 |
+
|
| 853 |
+
sys.modules[__name__] = _LazyModule(
|
| 854 |
+
__name__,
|
| 855 |
+
globals()["__file__"],
|
| 856 |
+
_import_structure,
|
| 857 |
+
module_spec=__spec__,
|
| 858 |
+
)
|
| 859 |
+
for name, value in _dummy_objects.items():
|
| 860 |
+
setattr(sys.modules[__name__], name, value)
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (18 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/auto_pipeline.cpython-310.pyc
ADDED
|
Binary file (43.2 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/free_init_utils.cpython-310.pyc
ADDED
|
Binary file (6.12 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/free_noise_utils.cpython-310.pyc
ADDED
|
Binary file (20.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/onnx_utils.cpython-310.pyc
ADDED
|
Binary file (7.12 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_flax_utils.cpython-310.pyc
ADDED
|
Binary file (18.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_loading_utils.cpython-310.pyc
ADDED
|
Binary file (29.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/pipeline_utils.cpython-310.pyc
ADDED
|
Binary file (77.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/__pycache__/transformers_loading_utils.cpython-310.pyc
ADDED
|
Binary file (4.05 kB). View file
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/auto_pipeline.py
ADDED
|
@@ -0,0 +1,1175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
|
| 16 |
+
from collections import OrderedDict
|
| 17 |
+
|
| 18 |
+
from huggingface_hub.utils import validate_hf_hub_args
|
| 19 |
+
|
| 20 |
+
from ..configuration_utils import ConfigMixin
|
| 21 |
+
from ..models.controlnets import ControlNetUnionModel
|
| 22 |
+
from ..utils import is_sentencepiece_available
|
| 23 |
+
from .aura_flow import AuraFlowPipeline
|
| 24 |
+
from .chroma import ChromaPipeline
|
| 25 |
+
from .cogview3 import CogView3PlusPipeline
|
| 26 |
+
from .cogview4 import CogView4ControlPipeline, CogView4Pipeline
|
| 27 |
+
from .controlnet import (
|
| 28 |
+
StableDiffusionControlNetImg2ImgPipeline,
|
| 29 |
+
StableDiffusionControlNetInpaintPipeline,
|
| 30 |
+
StableDiffusionControlNetPipeline,
|
| 31 |
+
StableDiffusionXLControlNetImg2ImgPipeline,
|
| 32 |
+
StableDiffusionXLControlNetInpaintPipeline,
|
| 33 |
+
StableDiffusionXLControlNetPipeline,
|
| 34 |
+
StableDiffusionXLControlNetUnionImg2ImgPipeline,
|
| 35 |
+
StableDiffusionXLControlNetUnionInpaintPipeline,
|
| 36 |
+
StableDiffusionXLControlNetUnionPipeline,
|
| 37 |
+
)
|
| 38 |
+
from .controlnet_sd3 import (
|
| 39 |
+
StableDiffusion3ControlNetInpaintingPipeline,
|
| 40 |
+
StableDiffusion3ControlNetPipeline,
|
| 41 |
+
)
|
| 42 |
+
from .deepfloyd_if import IFImg2ImgPipeline, IFInpaintingPipeline, IFPipeline
|
| 43 |
+
from .flux import (
|
| 44 |
+
FluxControlImg2ImgPipeline,
|
| 45 |
+
FluxControlInpaintPipeline,
|
| 46 |
+
FluxControlNetImg2ImgPipeline,
|
| 47 |
+
FluxControlNetInpaintPipeline,
|
| 48 |
+
FluxControlNetPipeline,
|
| 49 |
+
FluxControlPipeline,
|
| 50 |
+
FluxImg2ImgPipeline,
|
| 51 |
+
FluxInpaintPipeline,
|
| 52 |
+
FluxPipeline,
|
| 53 |
+
)
|
| 54 |
+
from .hunyuandit import HunyuanDiTPipeline
|
| 55 |
+
from .kandinsky import (
|
| 56 |
+
KandinskyCombinedPipeline,
|
| 57 |
+
KandinskyImg2ImgCombinedPipeline,
|
| 58 |
+
KandinskyImg2ImgPipeline,
|
| 59 |
+
KandinskyInpaintCombinedPipeline,
|
| 60 |
+
KandinskyInpaintPipeline,
|
| 61 |
+
KandinskyPipeline,
|
| 62 |
+
)
|
| 63 |
+
from .kandinsky2_2 import (
|
| 64 |
+
KandinskyV22CombinedPipeline,
|
| 65 |
+
KandinskyV22Img2ImgCombinedPipeline,
|
| 66 |
+
KandinskyV22Img2ImgPipeline,
|
| 67 |
+
KandinskyV22InpaintCombinedPipeline,
|
| 68 |
+
KandinskyV22InpaintPipeline,
|
| 69 |
+
KandinskyV22Pipeline,
|
| 70 |
+
)
|
| 71 |
+
from .kandinsky3 import Kandinsky3Img2ImgPipeline, Kandinsky3Pipeline
|
| 72 |
+
from .latent_consistency_models import LatentConsistencyModelImg2ImgPipeline, LatentConsistencyModelPipeline
|
| 73 |
+
from .lumina import LuminaPipeline
|
| 74 |
+
from .lumina2 import Lumina2Pipeline
|
| 75 |
+
from .pag import (
|
| 76 |
+
HunyuanDiTPAGPipeline,
|
| 77 |
+
PixArtSigmaPAGPipeline,
|
| 78 |
+
SanaPAGPipeline,
|
| 79 |
+
StableDiffusion3PAGImg2ImgPipeline,
|
| 80 |
+
StableDiffusion3PAGPipeline,
|
| 81 |
+
StableDiffusionControlNetPAGInpaintPipeline,
|
| 82 |
+
StableDiffusionControlNetPAGPipeline,
|
| 83 |
+
StableDiffusionPAGImg2ImgPipeline,
|
| 84 |
+
StableDiffusionPAGInpaintPipeline,
|
| 85 |
+
StableDiffusionPAGPipeline,
|
| 86 |
+
StableDiffusionXLControlNetPAGImg2ImgPipeline,
|
| 87 |
+
StableDiffusionXLControlNetPAGPipeline,
|
| 88 |
+
StableDiffusionXLPAGImg2ImgPipeline,
|
| 89 |
+
StableDiffusionXLPAGInpaintPipeline,
|
| 90 |
+
StableDiffusionXLPAGPipeline,
|
| 91 |
+
)
|
| 92 |
+
from .pixart_alpha import PixArtAlphaPipeline, PixArtSigmaPipeline
|
| 93 |
+
from .sana import SanaPipeline
|
| 94 |
+
from .stable_cascade import StableCascadeCombinedPipeline, StableCascadeDecoderPipeline
|
| 95 |
+
from .stable_diffusion import (
|
| 96 |
+
StableDiffusionImg2ImgPipeline,
|
| 97 |
+
StableDiffusionInpaintPipeline,
|
| 98 |
+
StableDiffusionPipeline,
|
| 99 |
+
)
|
| 100 |
+
from .stable_diffusion_3 import (
|
| 101 |
+
StableDiffusion3Img2ImgPipeline,
|
| 102 |
+
StableDiffusion3InpaintPipeline,
|
| 103 |
+
StableDiffusion3Pipeline,
|
| 104 |
+
)
|
| 105 |
+
from .stable_diffusion_xl import (
|
| 106 |
+
StableDiffusionXLImg2ImgPipeline,
|
| 107 |
+
StableDiffusionXLInpaintPipeline,
|
| 108 |
+
StableDiffusionXLPipeline,
|
| 109 |
+
)
|
| 110 |
+
from .wuerstchen import WuerstchenCombinedPipeline, WuerstchenDecoderPipeline
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING = OrderedDict(
|
| 114 |
+
[
|
| 115 |
+
("stable-diffusion", StableDiffusionPipeline),
|
| 116 |
+
("stable-diffusion-xl", StableDiffusionXLPipeline),
|
| 117 |
+
("stable-diffusion-3", StableDiffusion3Pipeline),
|
| 118 |
+
("stable-diffusion-3-pag", StableDiffusion3PAGPipeline),
|
| 119 |
+
("if", IFPipeline),
|
| 120 |
+
("hunyuan", HunyuanDiTPipeline),
|
| 121 |
+
("hunyuan-pag", HunyuanDiTPAGPipeline),
|
| 122 |
+
("kandinsky", KandinskyCombinedPipeline),
|
| 123 |
+
("kandinsky22", KandinskyV22CombinedPipeline),
|
| 124 |
+
("kandinsky3", Kandinsky3Pipeline),
|
| 125 |
+
("stable-diffusion-controlnet", StableDiffusionControlNetPipeline),
|
| 126 |
+
("stable-diffusion-xl-controlnet", StableDiffusionXLControlNetPipeline),
|
| 127 |
+
("stable-diffusion-xl-controlnet-union", StableDiffusionXLControlNetUnionPipeline),
|
| 128 |
+
("stable-diffusion-3-controlnet", StableDiffusion3ControlNetPipeline),
|
| 129 |
+
("wuerstchen", WuerstchenCombinedPipeline),
|
| 130 |
+
("cascade", StableCascadeCombinedPipeline),
|
| 131 |
+
("lcm", LatentConsistencyModelPipeline),
|
| 132 |
+
("pixart-alpha", PixArtAlphaPipeline),
|
| 133 |
+
("pixart-sigma", PixArtSigmaPipeline),
|
| 134 |
+
("sana", SanaPipeline),
|
| 135 |
+
("sana-pag", SanaPAGPipeline),
|
| 136 |
+
("stable-diffusion-pag", StableDiffusionPAGPipeline),
|
| 137 |
+
("stable-diffusion-controlnet-pag", StableDiffusionControlNetPAGPipeline),
|
| 138 |
+
("stable-diffusion-xl-pag", StableDiffusionXLPAGPipeline),
|
| 139 |
+
("stable-diffusion-xl-controlnet-pag", StableDiffusionXLControlNetPAGPipeline),
|
| 140 |
+
("pixart-sigma-pag", PixArtSigmaPAGPipeline),
|
| 141 |
+
("auraflow", AuraFlowPipeline),
|
| 142 |
+
("flux", FluxPipeline),
|
| 143 |
+
("flux-control", FluxControlPipeline),
|
| 144 |
+
("flux-controlnet", FluxControlNetPipeline),
|
| 145 |
+
("lumina", LuminaPipeline),
|
| 146 |
+
("lumina2", Lumina2Pipeline),
|
| 147 |
+
("chroma", ChromaPipeline),
|
| 148 |
+
("cogview3", CogView3PlusPipeline),
|
| 149 |
+
("cogview4", CogView4Pipeline),
|
| 150 |
+
("cogview4-control", CogView4ControlPipeline),
|
| 151 |
+
]
|
| 152 |
+
)
|
| 153 |
+
|
| 154 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING = OrderedDict(
|
| 155 |
+
[
|
| 156 |
+
("stable-diffusion", StableDiffusionImg2ImgPipeline),
|
| 157 |
+
("stable-diffusion-xl", StableDiffusionXLImg2ImgPipeline),
|
| 158 |
+
("stable-diffusion-3", StableDiffusion3Img2ImgPipeline),
|
| 159 |
+
("stable-diffusion-3-pag", StableDiffusion3PAGImg2ImgPipeline),
|
| 160 |
+
("if", IFImg2ImgPipeline),
|
| 161 |
+
("kandinsky", KandinskyImg2ImgCombinedPipeline),
|
| 162 |
+
("kandinsky22", KandinskyV22Img2ImgCombinedPipeline),
|
| 163 |
+
("kandinsky3", Kandinsky3Img2ImgPipeline),
|
| 164 |
+
("stable-diffusion-controlnet", StableDiffusionControlNetImg2ImgPipeline),
|
| 165 |
+
("stable-diffusion-pag", StableDiffusionPAGImg2ImgPipeline),
|
| 166 |
+
("stable-diffusion-xl-controlnet", StableDiffusionXLControlNetImg2ImgPipeline),
|
| 167 |
+
("stable-diffusion-xl-controlnet-union", StableDiffusionXLControlNetUnionImg2ImgPipeline),
|
| 168 |
+
("stable-diffusion-xl-pag", StableDiffusionXLPAGImg2ImgPipeline),
|
| 169 |
+
("stable-diffusion-xl-controlnet-pag", StableDiffusionXLControlNetPAGImg2ImgPipeline),
|
| 170 |
+
("lcm", LatentConsistencyModelImg2ImgPipeline),
|
| 171 |
+
("flux", FluxImg2ImgPipeline),
|
| 172 |
+
("flux-controlnet", FluxControlNetImg2ImgPipeline),
|
| 173 |
+
("flux-control", FluxControlImg2ImgPipeline),
|
| 174 |
+
]
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
AUTO_INPAINT_PIPELINES_MAPPING = OrderedDict(
|
| 178 |
+
[
|
| 179 |
+
("stable-diffusion", StableDiffusionInpaintPipeline),
|
| 180 |
+
("stable-diffusion-xl", StableDiffusionXLInpaintPipeline),
|
| 181 |
+
("stable-diffusion-3", StableDiffusion3InpaintPipeline),
|
| 182 |
+
("if", IFInpaintingPipeline),
|
| 183 |
+
("kandinsky", KandinskyInpaintCombinedPipeline),
|
| 184 |
+
("kandinsky22", KandinskyV22InpaintCombinedPipeline),
|
| 185 |
+
("stable-diffusion-controlnet", StableDiffusionControlNetInpaintPipeline),
|
| 186 |
+
("stable-diffusion-controlnet-pag", StableDiffusionControlNetPAGInpaintPipeline),
|
| 187 |
+
("stable-diffusion-xl-controlnet", StableDiffusionXLControlNetInpaintPipeline),
|
| 188 |
+
("stable-diffusion-xl-controlnet-union", StableDiffusionXLControlNetUnionInpaintPipeline),
|
| 189 |
+
("stable-diffusion-3-controlnet", StableDiffusion3ControlNetInpaintingPipeline),
|
| 190 |
+
("stable-diffusion-xl-pag", StableDiffusionXLPAGInpaintPipeline),
|
| 191 |
+
("flux", FluxInpaintPipeline),
|
| 192 |
+
("flux-controlnet", FluxControlNetInpaintPipeline),
|
| 193 |
+
("flux-control", FluxControlInpaintPipeline),
|
| 194 |
+
("stable-diffusion-pag", StableDiffusionPAGInpaintPipeline),
|
| 195 |
+
]
|
| 196 |
+
)
|
| 197 |
+
|
| 198 |
+
_AUTO_TEXT2IMAGE_DECODER_PIPELINES_MAPPING = OrderedDict(
|
| 199 |
+
[
|
| 200 |
+
("kandinsky", KandinskyPipeline),
|
| 201 |
+
("kandinsky22", KandinskyV22Pipeline),
|
| 202 |
+
("wuerstchen", WuerstchenDecoderPipeline),
|
| 203 |
+
("cascade", StableCascadeDecoderPipeline),
|
| 204 |
+
]
|
| 205 |
+
)
|
| 206 |
+
_AUTO_IMAGE2IMAGE_DECODER_PIPELINES_MAPPING = OrderedDict(
|
| 207 |
+
[
|
| 208 |
+
("kandinsky", KandinskyImg2ImgPipeline),
|
| 209 |
+
("kandinsky22", KandinskyV22Img2ImgPipeline),
|
| 210 |
+
]
|
| 211 |
+
)
|
| 212 |
+
_AUTO_INPAINT_DECODER_PIPELINES_MAPPING = OrderedDict(
|
| 213 |
+
[
|
| 214 |
+
("kandinsky", KandinskyInpaintPipeline),
|
| 215 |
+
("kandinsky22", KandinskyV22InpaintPipeline),
|
| 216 |
+
]
|
| 217 |
+
)
|
| 218 |
+
|
| 219 |
+
if is_sentencepiece_available():
|
| 220 |
+
from .kolors import KolorsImg2ImgPipeline, KolorsPipeline
|
| 221 |
+
from .pag import KolorsPAGPipeline
|
| 222 |
+
|
| 223 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING["kolors"] = KolorsPipeline
|
| 224 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING["kolors-pag"] = KolorsPAGPipeline
|
| 225 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING["kolors"] = KolorsImg2ImgPipeline
|
| 226 |
+
|
| 227 |
+
SUPPORTED_TASKS_MAPPINGS = [
|
| 228 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING,
|
| 229 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING,
|
| 230 |
+
AUTO_INPAINT_PIPELINES_MAPPING,
|
| 231 |
+
_AUTO_TEXT2IMAGE_DECODER_PIPELINES_MAPPING,
|
| 232 |
+
_AUTO_IMAGE2IMAGE_DECODER_PIPELINES_MAPPING,
|
| 233 |
+
_AUTO_INPAINT_DECODER_PIPELINES_MAPPING,
|
| 234 |
+
]
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
def _get_connected_pipeline(pipeline_cls):
|
| 238 |
+
# for now connected pipelines can only be loaded from decoder pipelines, such as kandinsky-community/kandinsky-2-2-decoder
|
| 239 |
+
if pipeline_cls in _AUTO_TEXT2IMAGE_DECODER_PIPELINES_MAPPING.values():
|
| 240 |
+
return _get_task_class(
|
| 241 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING, pipeline_cls.__name__, throw_error_if_not_exist=False
|
| 242 |
+
)
|
| 243 |
+
if pipeline_cls in _AUTO_IMAGE2IMAGE_DECODER_PIPELINES_MAPPING.values():
|
| 244 |
+
return _get_task_class(
|
| 245 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING, pipeline_cls.__name__, throw_error_if_not_exist=False
|
| 246 |
+
)
|
| 247 |
+
if pipeline_cls in _AUTO_INPAINT_DECODER_PIPELINES_MAPPING.values():
|
| 248 |
+
return _get_task_class(AUTO_INPAINT_PIPELINES_MAPPING, pipeline_cls.__name__, throw_error_if_not_exist=False)
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def _get_task_class(mapping, pipeline_class_name, throw_error_if_not_exist: bool = True):
|
| 252 |
+
def get_model(pipeline_class_name):
|
| 253 |
+
for task_mapping in SUPPORTED_TASKS_MAPPINGS:
|
| 254 |
+
for model_name, pipeline in task_mapping.items():
|
| 255 |
+
if pipeline.__name__ == pipeline_class_name:
|
| 256 |
+
return model_name
|
| 257 |
+
|
| 258 |
+
model_name = get_model(pipeline_class_name)
|
| 259 |
+
|
| 260 |
+
if model_name is not None:
|
| 261 |
+
task_class = mapping.get(model_name, None)
|
| 262 |
+
if task_class is not None:
|
| 263 |
+
return task_class
|
| 264 |
+
|
| 265 |
+
if throw_error_if_not_exist:
|
| 266 |
+
raise ValueError(f"AutoPipeline can't find a pipeline linked to {pipeline_class_name} for {model_name}")
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
class AutoPipelineForText2Image(ConfigMixin):
|
| 270 |
+
r"""
|
| 271 |
+
|
| 272 |
+
[`AutoPipelineForText2Image`] is a generic pipeline class that instantiates a text-to-image pipeline class. The
|
| 273 |
+
specific underlying pipeline class is automatically selected from either the
|
| 274 |
+
[`~AutoPipelineForText2Image.from_pretrained`] or [`~AutoPipelineForText2Image.from_pipe`] methods.
|
| 275 |
+
|
| 276 |
+
This class cannot be instantiated using `__init__()` (throws an error).
|
| 277 |
+
|
| 278 |
+
Class attributes:
|
| 279 |
+
|
| 280 |
+
- **config_name** (`str`) -- The configuration filename that stores the class and module names of all the
|
| 281 |
+
diffusion pipeline's components.
|
| 282 |
+
|
| 283 |
+
"""
|
| 284 |
+
|
| 285 |
+
config_name = "model_index.json"
|
| 286 |
+
|
| 287 |
+
def __init__(self, *args, **kwargs):
|
| 288 |
+
raise EnvironmentError(
|
| 289 |
+
f"{self.__class__.__name__} is designed to be instantiated "
|
| 290 |
+
f"using the `{self.__class__.__name__}.from_pretrained(pretrained_model_name_or_path)` or "
|
| 291 |
+
f"`{self.__class__.__name__}.from_pipe(pipeline)` methods."
|
| 292 |
+
)
|
| 293 |
+
|
| 294 |
+
@classmethod
|
| 295 |
+
@validate_hf_hub_args
|
| 296 |
+
def from_pretrained(cls, pretrained_model_or_path, **kwargs):
|
| 297 |
+
r"""
|
| 298 |
+
Instantiates a text-to-image Pytorch diffusion pipeline from pretrained pipeline weight.
|
| 299 |
+
|
| 300 |
+
The from_pretrained() method takes care of returning the correct pipeline class instance by:
|
| 301 |
+
1. Detect the pipeline class of the pretrained_model_or_path based on the _class_name property of its
|
| 302 |
+
config object
|
| 303 |
+
2. Find the text-to-image pipeline linked to the pipeline class using pattern matching on pipeline class
|
| 304 |
+
name.
|
| 305 |
+
|
| 306 |
+
If a `controlnet` argument is passed, it will instantiate a [`StableDiffusionControlNetPipeline`] object.
|
| 307 |
+
|
| 308 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 309 |
+
|
| 310 |
+
If you get the error message below, you need to finetune the weights for your downstream task:
|
| 311 |
+
|
| 312 |
+
```
|
| 313 |
+
Some weights of UNet2DConditionModel were not initialized from the model checkpoint at stable-diffusion-v1-5/stable-diffusion-v1-5 and are newly initialized because the shapes did not match:
|
| 314 |
+
- conv_in.weight: found shape torch.Size([320, 4, 3, 3]) in the checkpoint and torch.Size([320, 9, 3, 3]) in the model instantiated
|
| 315 |
+
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
|
| 316 |
+
```
|
| 317 |
+
|
| 318 |
+
Parameters:
|
| 319 |
+
pretrained_model_or_path (`str` or `os.PathLike`, *optional*):
|
| 320 |
+
Can be either:
|
| 321 |
+
|
| 322 |
+
- A string, the *repo id* (for example `CompVis/ldm-text2im-large-256`) of a pretrained pipeline
|
| 323 |
+
hosted on the Hub.
|
| 324 |
+
- A path to a *directory* (for example `./my_pipeline_directory/`) containing pipeline weights
|
| 325 |
+
saved using
|
| 326 |
+
[`~DiffusionPipeline.save_pretrained`].
|
| 327 |
+
torch_dtype (`torch.dtype`, *optional*):
|
| 328 |
+
Override the default `torch.dtype` and load the model with another dtype.
|
| 329 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 330 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 331 |
+
cached versions if they exist.
|
| 332 |
+
cache_dir (`Union[str, os.PathLike]`, *optional*):
|
| 333 |
+
Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
|
| 334 |
+
is not used.
|
| 335 |
+
|
| 336 |
+
proxies (`Dict[str, str]`, *optional*):
|
| 337 |
+
A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
|
| 338 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 339 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 340 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 341 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 342 |
+
Whether to only load local model weights and configuration files or not. If set to `True`, the model
|
| 343 |
+
won't be downloaded from the Hub.
|
| 344 |
+
token (`str` or *bool*, *optional*):
|
| 345 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
|
| 346 |
+
`diffusers-cli login` (stored in `~/.huggingface`) is used.
|
| 347 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 348 |
+
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
| 349 |
+
allowed by Git.
|
| 350 |
+
custom_revision (`str`, *optional*, defaults to `"main"`):
|
| 351 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id similar to
|
| 352 |
+
`revision` when loading a custom pipeline from the Hub. It can be a 🤗 Diffusers version when loading a
|
| 353 |
+
custom pipeline from GitHub, otherwise it defaults to `"main"` when loading from the Hub.
|
| 354 |
+
mirror (`str`, *optional*):
|
| 355 |
+
Mirror source to resolve accessibility issues if you’re downloading a model in China. We do not
|
| 356 |
+
guarantee the timeliness or safety of the source, and you should refer to the mirror site for more
|
| 357 |
+
information.
|
| 358 |
+
device_map (`str` or `Dict[str, Union[int, str, torch.device]]`, *optional*):
|
| 359 |
+
A map that specifies where each submodule should go. It doesn’t need to be defined for each
|
| 360 |
+
parameter/buffer name; once a given module name is inside, every submodule of it will be sent to the
|
| 361 |
+
same device.
|
| 362 |
+
|
| 363 |
+
Set `device_map="auto"` to have 🤗 Accelerate automatically compute the most optimized `device_map`. For
|
| 364 |
+
more information about each option see [designing a device
|
| 365 |
+
map](https://hf.co/docs/accelerate/main/en/usage_guides/big_modeling#designing-a-device-map).
|
| 366 |
+
max_memory (`Dict`, *optional*):
|
| 367 |
+
A dictionary device identifier for the maximum memory. Will default to the maximum memory available for
|
| 368 |
+
each GPU and the available CPU RAM if unset.
|
| 369 |
+
offload_folder (`str` or `os.PathLike`, *optional*):
|
| 370 |
+
The path to offload weights if device_map contains the value `"disk"`.
|
| 371 |
+
offload_state_dict (`bool`, *optional*):
|
| 372 |
+
If `True`, temporarily offloads the CPU state dict to the hard drive to avoid running out of CPU RAM if
|
| 373 |
+
the weight of the CPU state dict + the biggest shard of the checkpoint does not fit. Defaults to `True`
|
| 374 |
+
when there is some disk offload.
|
| 375 |
+
low_cpu_mem_usage (`bool`, *optional*, defaults to `True` if torch version >= 1.9.0 else `False`):
|
| 376 |
+
Speed up model loading only loading the pretrained weights and not initializing the weights. This also
|
| 377 |
+
tries to not use more than 1x model size in CPU memory (including peak memory) while loading the model.
|
| 378 |
+
Only supported for PyTorch >= 1.9.0. If you are using an older version of PyTorch, setting this
|
| 379 |
+
argument to `True` will raise an error.
|
| 380 |
+
use_safetensors (`bool`, *optional*, defaults to `None`):
|
| 381 |
+
If set to `None`, the safetensors weights are downloaded if they're available **and** if the
|
| 382 |
+
safetensors library is installed. If set to `True`, the model is forcibly loaded from safetensors
|
| 383 |
+
weights. If set to `False`, safetensors weights are not loaded.
|
| 384 |
+
kwargs (remaining dictionary of keyword arguments, *optional*):
|
| 385 |
+
Can be used to overwrite load and saveable variables (the pipeline components of the specific pipeline
|
| 386 |
+
class). The overwritten components are passed directly to the pipelines `__init__` method. See example
|
| 387 |
+
below for more information.
|
| 388 |
+
variant (`str`, *optional*):
|
| 389 |
+
Load weights from a specified variant filename such as `"fp16"` or `"ema"`. This is ignored when
|
| 390 |
+
loading `from_flax`.
|
| 391 |
+
|
| 392 |
+
<Tip>
|
| 393 |
+
|
| 394 |
+
To use private or [gated](https://huggingface.co/docs/hub/models-gated#gated-models) models, log-in with
|
| 395 |
+
`huggingface-cli login`.
|
| 396 |
+
|
| 397 |
+
</Tip>
|
| 398 |
+
|
| 399 |
+
Examples:
|
| 400 |
+
|
| 401 |
+
```py
|
| 402 |
+
>>> from diffusers import AutoPipelineForText2Image
|
| 403 |
+
|
| 404 |
+
>>> pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5")
|
| 405 |
+
>>> image = pipeline(prompt).images[0]
|
| 406 |
+
```
|
| 407 |
+
"""
|
| 408 |
+
cache_dir = kwargs.pop("cache_dir", None)
|
| 409 |
+
force_download = kwargs.pop("force_download", False)
|
| 410 |
+
proxies = kwargs.pop("proxies", None)
|
| 411 |
+
token = kwargs.pop("token", None)
|
| 412 |
+
local_files_only = kwargs.pop("local_files_only", False)
|
| 413 |
+
revision = kwargs.pop("revision", None)
|
| 414 |
+
|
| 415 |
+
load_config_kwargs = {
|
| 416 |
+
"cache_dir": cache_dir,
|
| 417 |
+
"force_download": force_download,
|
| 418 |
+
"proxies": proxies,
|
| 419 |
+
"token": token,
|
| 420 |
+
"local_files_only": local_files_only,
|
| 421 |
+
"revision": revision,
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
config = cls.load_config(pretrained_model_or_path, **load_config_kwargs)
|
| 425 |
+
orig_class_name = config["_class_name"]
|
| 426 |
+
if "ControlPipeline" in orig_class_name:
|
| 427 |
+
to_replace = "ControlPipeline"
|
| 428 |
+
else:
|
| 429 |
+
to_replace = "Pipeline"
|
| 430 |
+
|
| 431 |
+
if "controlnet" in kwargs:
|
| 432 |
+
if isinstance(kwargs["controlnet"], ControlNetUnionModel):
|
| 433 |
+
orig_class_name = config["_class_name"].replace(to_replace, "ControlNetUnionPipeline")
|
| 434 |
+
else:
|
| 435 |
+
orig_class_name = config["_class_name"].replace(to_replace, "ControlNetPipeline")
|
| 436 |
+
if "enable_pag" in kwargs:
|
| 437 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 438 |
+
if enable_pag:
|
| 439 |
+
orig_class_name = orig_class_name.replace(to_replace, "PAGPipeline")
|
| 440 |
+
|
| 441 |
+
text_2_image_cls = _get_task_class(AUTO_TEXT2IMAGE_PIPELINES_MAPPING, orig_class_name)
|
| 442 |
+
|
| 443 |
+
kwargs = {**load_config_kwargs, **kwargs}
|
| 444 |
+
return text_2_image_cls.from_pretrained(pretrained_model_or_path, **kwargs)
|
| 445 |
+
|
| 446 |
+
@classmethod
|
| 447 |
+
def from_pipe(cls, pipeline, **kwargs):
|
| 448 |
+
r"""
|
| 449 |
+
Instantiates a text-to-image Pytorch diffusion pipeline from another instantiated diffusion pipeline class.
|
| 450 |
+
|
| 451 |
+
The from_pipe() method takes care of returning the correct pipeline class instance by finding the text-to-image
|
| 452 |
+
pipeline linked to the pipeline class using pattern matching on pipeline class name.
|
| 453 |
+
|
| 454 |
+
All the modules the pipeline contains will be used to initialize the new pipeline without reallocating
|
| 455 |
+
additional memory.
|
| 456 |
+
|
| 457 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 458 |
+
|
| 459 |
+
Parameters:
|
| 460 |
+
pipeline (`DiffusionPipeline`):
|
| 461 |
+
an instantiated `DiffusionPipeline` object
|
| 462 |
+
|
| 463 |
+
```py
|
| 464 |
+
>>> from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image
|
| 465 |
+
|
| 466 |
+
>>> pipe_i2i = AutoPipelineForImage2Image.from_pretrained(
|
| 467 |
+
... "stable-diffusion-v1-5/stable-diffusion-v1-5", requires_safety_checker=False
|
| 468 |
+
... )
|
| 469 |
+
|
| 470 |
+
>>> pipe_t2i = AutoPipelineForText2Image.from_pipe(pipe_i2i)
|
| 471 |
+
>>> image = pipe_t2i(prompt).images[0]
|
| 472 |
+
```
|
| 473 |
+
"""
|
| 474 |
+
|
| 475 |
+
original_config = dict(pipeline.config)
|
| 476 |
+
original_cls_name = pipeline.__class__.__name__
|
| 477 |
+
|
| 478 |
+
# derive the pipeline class to instantiate
|
| 479 |
+
text_2_image_cls = _get_task_class(AUTO_TEXT2IMAGE_PIPELINES_MAPPING, original_cls_name)
|
| 480 |
+
|
| 481 |
+
if "controlnet" in kwargs:
|
| 482 |
+
if kwargs["controlnet"] is not None:
|
| 483 |
+
to_replace = "PAGPipeline" if "PAG" in text_2_image_cls.__name__ else "Pipeline"
|
| 484 |
+
text_2_image_cls = _get_task_class(
|
| 485 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING,
|
| 486 |
+
text_2_image_cls.__name__.replace("ControlNet", "").replace(to_replace, "ControlNet" + to_replace),
|
| 487 |
+
)
|
| 488 |
+
else:
|
| 489 |
+
text_2_image_cls = _get_task_class(
|
| 490 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING,
|
| 491 |
+
text_2_image_cls.__name__.replace("ControlNet", ""),
|
| 492 |
+
)
|
| 493 |
+
|
| 494 |
+
if "enable_pag" in kwargs:
|
| 495 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 496 |
+
if enable_pag:
|
| 497 |
+
text_2_image_cls = _get_task_class(
|
| 498 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING,
|
| 499 |
+
text_2_image_cls.__name__.replace("PAG", "").replace("Pipeline", "PAGPipeline"),
|
| 500 |
+
)
|
| 501 |
+
else:
|
| 502 |
+
text_2_image_cls = _get_task_class(
|
| 503 |
+
AUTO_TEXT2IMAGE_PIPELINES_MAPPING,
|
| 504 |
+
text_2_image_cls.__name__.replace("PAG", ""),
|
| 505 |
+
)
|
| 506 |
+
|
| 507 |
+
# define expected module and optional kwargs given the pipeline signature
|
| 508 |
+
expected_modules, optional_kwargs = text_2_image_cls._get_signature_keys(text_2_image_cls)
|
| 509 |
+
|
| 510 |
+
pretrained_model_name_or_path = original_config.pop("_name_or_path", None)
|
| 511 |
+
|
| 512 |
+
# allow users pass modules in `kwargs` to override the original pipeline's components
|
| 513 |
+
passed_class_obj = {k: kwargs.pop(k) for k in expected_modules if k in kwargs}
|
| 514 |
+
original_class_obj = {
|
| 515 |
+
k: pipeline.components[k]
|
| 516 |
+
for k, v in pipeline.components.items()
|
| 517 |
+
if k in expected_modules and k not in passed_class_obj
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
# allow users pass optional kwargs to override the original pipelines config attribute
|
| 521 |
+
passed_pipe_kwargs = {k: kwargs.pop(k) for k in optional_kwargs if k in kwargs}
|
| 522 |
+
original_pipe_kwargs = {
|
| 523 |
+
k: original_config[k]
|
| 524 |
+
for k, v in original_config.items()
|
| 525 |
+
if k in optional_kwargs and k not in passed_pipe_kwargs
|
| 526 |
+
}
|
| 527 |
+
|
| 528 |
+
# config that were not expected by original pipeline is stored as private attribute
|
| 529 |
+
# we will pass them as optional arguments if they can be accepted by the pipeline
|
| 530 |
+
additional_pipe_kwargs = [
|
| 531 |
+
k[1:]
|
| 532 |
+
for k in original_config.keys()
|
| 533 |
+
if k.startswith("_") and k[1:] in optional_kwargs and k[1:] not in passed_pipe_kwargs
|
| 534 |
+
]
|
| 535 |
+
for k in additional_pipe_kwargs:
|
| 536 |
+
original_pipe_kwargs[k] = original_config.pop(f"_{k}")
|
| 537 |
+
|
| 538 |
+
text_2_image_kwargs = {**passed_class_obj, **original_class_obj, **passed_pipe_kwargs, **original_pipe_kwargs}
|
| 539 |
+
|
| 540 |
+
# store unused config as private attribute
|
| 541 |
+
unused_original_config = {
|
| 542 |
+
f"{'' if k.startswith('_') else '_'}{k}": original_config[k]
|
| 543 |
+
for k, v in original_config.items()
|
| 544 |
+
if k not in text_2_image_kwargs
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
missing_modules = (
|
| 548 |
+
set(expected_modules) - set(text_2_image_cls._optional_components) - set(text_2_image_kwargs.keys())
|
| 549 |
+
)
|
| 550 |
+
|
| 551 |
+
if len(missing_modules) > 0:
|
| 552 |
+
raise ValueError(
|
| 553 |
+
f"Pipeline {text_2_image_cls} expected {expected_modules}, but only {set(list(passed_class_obj.keys()) + list(original_class_obj.keys()))} were passed"
|
| 554 |
+
)
|
| 555 |
+
|
| 556 |
+
model = text_2_image_cls(**text_2_image_kwargs)
|
| 557 |
+
model.register_to_config(_name_or_path=pretrained_model_name_or_path)
|
| 558 |
+
model.register_to_config(**unused_original_config)
|
| 559 |
+
|
| 560 |
+
return model
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
class AutoPipelineForImage2Image(ConfigMixin):
|
| 564 |
+
r"""
|
| 565 |
+
|
| 566 |
+
[`AutoPipelineForImage2Image`] is a generic pipeline class that instantiates an image-to-image pipeline class. The
|
| 567 |
+
specific underlying pipeline class is automatically selected from either the
|
| 568 |
+
[`~AutoPipelineForImage2Image.from_pretrained`] or [`~AutoPipelineForImage2Image.from_pipe`] methods.
|
| 569 |
+
|
| 570 |
+
This class cannot be instantiated using `__init__()` (throws an error).
|
| 571 |
+
|
| 572 |
+
Class attributes:
|
| 573 |
+
|
| 574 |
+
- **config_name** (`str`) -- The configuration filename that stores the class and module names of all the
|
| 575 |
+
diffusion pipeline's components.
|
| 576 |
+
|
| 577 |
+
"""
|
| 578 |
+
|
| 579 |
+
config_name = "model_index.json"
|
| 580 |
+
|
| 581 |
+
def __init__(self, *args, **kwargs):
|
| 582 |
+
raise EnvironmentError(
|
| 583 |
+
f"{self.__class__.__name__} is designed to be instantiated "
|
| 584 |
+
f"using the `{self.__class__.__name__}.from_pretrained(pretrained_model_name_or_path)` or "
|
| 585 |
+
f"`{self.__class__.__name__}.from_pipe(pipeline)` methods."
|
| 586 |
+
)
|
| 587 |
+
|
| 588 |
+
@classmethod
|
| 589 |
+
@validate_hf_hub_args
|
| 590 |
+
def from_pretrained(cls, pretrained_model_or_path, **kwargs):
|
| 591 |
+
r"""
|
| 592 |
+
Instantiates a image-to-image Pytorch diffusion pipeline from pretrained pipeline weight.
|
| 593 |
+
|
| 594 |
+
The from_pretrained() method takes care of returning the correct pipeline class instance by:
|
| 595 |
+
1. Detect the pipeline class of the pretrained_model_or_path based on the _class_name property of its
|
| 596 |
+
config object
|
| 597 |
+
2. Find the image-to-image pipeline linked to the pipeline class using pattern matching on pipeline class
|
| 598 |
+
name.
|
| 599 |
+
|
| 600 |
+
If a `controlnet` argument is passed, it will instantiate a [`StableDiffusionControlNetImg2ImgPipeline`]
|
| 601 |
+
object.
|
| 602 |
+
|
| 603 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 604 |
+
|
| 605 |
+
If you get the error message below, you need to finetune the weights for your downstream task:
|
| 606 |
+
|
| 607 |
+
```
|
| 608 |
+
Some weights of UNet2DConditionModel were not initialized from the model checkpoint at stable-diffusion-v1-5/stable-diffusion-v1-5 and are newly initialized because the shapes did not match:
|
| 609 |
+
- conv_in.weight: found shape torch.Size([320, 4, 3, 3]) in the checkpoint and torch.Size([320, 9, 3, 3]) in the model instantiated
|
| 610 |
+
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
|
| 611 |
+
```
|
| 612 |
+
|
| 613 |
+
Parameters:
|
| 614 |
+
pretrained_model_or_path (`str` or `os.PathLike`, *optional*):
|
| 615 |
+
Can be either:
|
| 616 |
+
|
| 617 |
+
- A string, the *repo id* (for example `CompVis/ldm-text2im-large-256`) of a pretrained pipeline
|
| 618 |
+
hosted on the Hub.
|
| 619 |
+
- A path to a *directory* (for example `./my_pipeline_directory/`) containing pipeline weights
|
| 620 |
+
saved using
|
| 621 |
+
[`~DiffusionPipeline.save_pretrained`].
|
| 622 |
+
torch_dtype (`str` or `torch.dtype`, *optional*):
|
| 623 |
+
Override the default `torch.dtype` and load the model with another dtype.
|
| 624 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 625 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 626 |
+
cached versions if they exist.
|
| 627 |
+
cache_dir (`Union[str, os.PathLike]`, *optional*):
|
| 628 |
+
Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
|
| 629 |
+
is not used.
|
| 630 |
+
|
| 631 |
+
proxies (`Dict[str, str]`, *optional*):
|
| 632 |
+
A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
|
| 633 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 634 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 635 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 636 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 637 |
+
Whether to only load local model weights and configuration files or not. If set to `True`, the model
|
| 638 |
+
won't be downloaded from the Hub.
|
| 639 |
+
token (`str` or *bool*, *optional*):
|
| 640 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
|
| 641 |
+
`diffusers-cli login` (stored in `~/.huggingface`) is used.
|
| 642 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 643 |
+
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
| 644 |
+
allowed by Git.
|
| 645 |
+
custom_revision (`str`, *optional*, defaults to `"main"`):
|
| 646 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id similar to
|
| 647 |
+
`revision` when loading a custom pipeline from the Hub. It can be a 🤗 Diffusers version when loading a
|
| 648 |
+
custom pipeline from GitHub, otherwise it defaults to `"main"` when loading from the Hub.
|
| 649 |
+
mirror (`str`, *optional*):
|
| 650 |
+
Mirror source to resolve accessibility issues if you’re downloading a model in China. We do not
|
| 651 |
+
guarantee the timeliness or safety of the source, and you should refer to the mirror site for more
|
| 652 |
+
information.
|
| 653 |
+
device_map (`str` or `Dict[str, Union[int, str, torch.device]]`, *optional*):
|
| 654 |
+
A map that specifies where each submodule should go. It doesn’t need to be defined for each
|
| 655 |
+
parameter/buffer name; once a given module name is inside, every submodule of it will be sent to the
|
| 656 |
+
same device.
|
| 657 |
+
|
| 658 |
+
Set `device_map="auto"` to have 🤗 Accelerate automatically compute the most optimized `device_map`. For
|
| 659 |
+
more information about each option see [designing a device
|
| 660 |
+
map](https://hf.co/docs/accelerate/main/en/usage_guides/big_modeling#designing-a-device-map).
|
| 661 |
+
max_memory (`Dict`, *optional*):
|
| 662 |
+
A dictionary device identifier for the maximum memory. Will default to the maximum memory available for
|
| 663 |
+
each GPU and the available CPU RAM if unset.
|
| 664 |
+
offload_folder (`str` or `os.PathLike`, *optional*):
|
| 665 |
+
The path to offload weights if device_map contains the value `"disk"`.
|
| 666 |
+
offload_state_dict (`bool`, *optional*):
|
| 667 |
+
If `True`, temporarily offloads the CPU state dict to the hard drive to avoid running out of CPU RAM if
|
| 668 |
+
the weight of the CPU state dict + the biggest shard of the checkpoint does not fit. Defaults to `True`
|
| 669 |
+
when there is some disk offload.
|
| 670 |
+
low_cpu_mem_usage (`bool`, *optional*, defaults to `True` if torch version >= 1.9.0 else `False`):
|
| 671 |
+
Speed up model loading only loading the pretrained weights and not initializing the weights. This also
|
| 672 |
+
tries to not use more than 1x model size in CPU memory (including peak memory) while loading the model.
|
| 673 |
+
Only supported for PyTorch >= 1.9.0. If you are using an older version of PyTorch, setting this
|
| 674 |
+
argument to `True` will raise an error.
|
| 675 |
+
use_safetensors (`bool`, *optional*, defaults to `None`):
|
| 676 |
+
If set to `None`, the safetensors weights are downloaded if they're available **and** if the
|
| 677 |
+
safetensors library is installed. If set to `True`, the model is forcibly loaded from safetensors
|
| 678 |
+
weights. If set to `False`, safetensors weights are not loaded.
|
| 679 |
+
kwargs (remaining dictionary of keyword arguments, *optional*):
|
| 680 |
+
Can be used to overwrite load and saveable variables (the pipeline components of the specific pipeline
|
| 681 |
+
class). The overwritten components are passed directly to the pipelines `__init__` method. See example
|
| 682 |
+
below for more information.
|
| 683 |
+
variant (`str`, *optional*):
|
| 684 |
+
Load weights from a specified variant filename such as `"fp16"` or `"ema"`. This is ignored when
|
| 685 |
+
loading `from_flax`.
|
| 686 |
+
|
| 687 |
+
<Tip>
|
| 688 |
+
|
| 689 |
+
To use private or [gated](https://huggingface.co/docs/hub/models-gated#gated-models) models, log-in with
|
| 690 |
+
`huggingface-cli login`.
|
| 691 |
+
|
| 692 |
+
</Tip>
|
| 693 |
+
|
| 694 |
+
Examples:
|
| 695 |
+
|
| 696 |
+
```py
|
| 697 |
+
>>> from diffusers import AutoPipelineForImage2Image
|
| 698 |
+
|
| 699 |
+
>>> pipeline = AutoPipelineForImage2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5")
|
| 700 |
+
>>> image = pipeline(prompt, image).images[0]
|
| 701 |
+
```
|
| 702 |
+
"""
|
| 703 |
+
cache_dir = kwargs.pop("cache_dir", None)
|
| 704 |
+
force_download = kwargs.pop("force_download", False)
|
| 705 |
+
proxies = kwargs.pop("proxies", None)
|
| 706 |
+
token = kwargs.pop("token", None)
|
| 707 |
+
local_files_only = kwargs.pop("local_files_only", False)
|
| 708 |
+
revision = kwargs.pop("revision", None)
|
| 709 |
+
|
| 710 |
+
load_config_kwargs = {
|
| 711 |
+
"cache_dir": cache_dir,
|
| 712 |
+
"force_download": force_download,
|
| 713 |
+
"proxies": proxies,
|
| 714 |
+
"token": token,
|
| 715 |
+
"local_files_only": local_files_only,
|
| 716 |
+
"revision": revision,
|
| 717 |
+
}
|
| 718 |
+
|
| 719 |
+
config = cls.load_config(pretrained_model_or_path, **load_config_kwargs)
|
| 720 |
+
orig_class_name = config["_class_name"]
|
| 721 |
+
|
| 722 |
+
# the `orig_class_name` can be:
|
| 723 |
+
# `- *Pipeline` (for regular text-to-image checkpoint)
|
| 724 |
+
# - `*ControlPipeline` (for Flux tools specific checkpoint)
|
| 725 |
+
# `- *Img2ImgPipeline` (for refiner checkpoint)
|
| 726 |
+
if "Img2Img" in orig_class_name:
|
| 727 |
+
to_replace = "Img2ImgPipeline"
|
| 728 |
+
elif "ControlPipeline" in orig_class_name:
|
| 729 |
+
to_replace = "ControlPipeline"
|
| 730 |
+
else:
|
| 731 |
+
to_replace = "Pipeline"
|
| 732 |
+
|
| 733 |
+
if "controlnet" in kwargs:
|
| 734 |
+
if isinstance(kwargs["controlnet"], ControlNetUnionModel):
|
| 735 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlNetUnion" + to_replace)
|
| 736 |
+
else:
|
| 737 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlNet" + to_replace)
|
| 738 |
+
if "enable_pag" in kwargs:
|
| 739 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 740 |
+
if enable_pag:
|
| 741 |
+
orig_class_name = orig_class_name.replace(to_replace, "PAG" + to_replace)
|
| 742 |
+
|
| 743 |
+
if to_replace == "ControlPipeline":
|
| 744 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlImg2ImgPipeline")
|
| 745 |
+
|
| 746 |
+
image_2_image_cls = _get_task_class(AUTO_IMAGE2IMAGE_PIPELINES_MAPPING, orig_class_name)
|
| 747 |
+
|
| 748 |
+
kwargs = {**load_config_kwargs, **kwargs}
|
| 749 |
+
return image_2_image_cls.from_pretrained(pretrained_model_or_path, **kwargs)
|
| 750 |
+
|
| 751 |
+
@classmethod
|
| 752 |
+
def from_pipe(cls, pipeline, **kwargs):
|
| 753 |
+
r"""
|
| 754 |
+
Instantiates a image-to-image Pytorch diffusion pipeline from another instantiated diffusion pipeline class.
|
| 755 |
+
|
| 756 |
+
The from_pipe() method takes care of returning the correct pipeline class instance by finding the
|
| 757 |
+
image-to-image pipeline linked to the pipeline class using pattern matching on pipeline class name.
|
| 758 |
+
|
| 759 |
+
All the modules the pipeline contains will be used to initialize the new pipeline without reallocating
|
| 760 |
+
additional memory.
|
| 761 |
+
|
| 762 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 763 |
+
|
| 764 |
+
Parameters:
|
| 765 |
+
pipeline (`DiffusionPipeline`):
|
| 766 |
+
an instantiated `DiffusionPipeline` object
|
| 767 |
+
|
| 768 |
+
Examples:
|
| 769 |
+
|
| 770 |
+
```py
|
| 771 |
+
>>> from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image
|
| 772 |
+
|
| 773 |
+
>>> pipe_t2i = AutoPipelineForText2Image.from_pretrained(
|
| 774 |
+
... "stable-diffusion-v1-5/stable-diffusion-v1-5", requires_safety_checker=False
|
| 775 |
+
... )
|
| 776 |
+
|
| 777 |
+
>>> pipe_i2i = AutoPipelineForImage2Image.from_pipe(pipe_t2i)
|
| 778 |
+
>>> image = pipe_i2i(prompt, image).images[0]
|
| 779 |
+
```
|
| 780 |
+
"""
|
| 781 |
+
|
| 782 |
+
original_config = dict(pipeline.config)
|
| 783 |
+
original_cls_name = pipeline.__class__.__name__
|
| 784 |
+
|
| 785 |
+
# derive the pipeline class to instantiate
|
| 786 |
+
image_2_image_cls = _get_task_class(AUTO_IMAGE2IMAGE_PIPELINES_MAPPING, original_cls_name)
|
| 787 |
+
|
| 788 |
+
if "controlnet" in kwargs:
|
| 789 |
+
if kwargs["controlnet"] is not None:
|
| 790 |
+
to_replace = "Img2ImgPipeline"
|
| 791 |
+
if "PAG" in image_2_image_cls.__name__:
|
| 792 |
+
to_replace = "PAG" + to_replace
|
| 793 |
+
image_2_image_cls = _get_task_class(
|
| 794 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING,
|
| 795 |
+
image_2_image_cls.__name__.replace("ControlNet", "").replace(
|
| 796 |
+
to_replace, "ControlNet" + to_replace
|
| 797 |
+
),
|
| 798 |
+
)
|
| 799 |
+
else:
|
| 800 |
+
image_2_image_cls = _get_task_class(
|
| 801 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING,
|
| 802 |
+
image_2_image_cls.__name__.replace("ControlNet", ""),
|
| 803 |
+
)
|
| 804 |
+
|
| 805 |
+
if "enable_pag" in kwargs:
|
| 806 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 807 |
+
if enable_pag:
|
| 808 |
+
image_2_image_cls = _get_task_class(
|
| 809 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING,
|
| 810 |
+
image_2_image_cls.__name__.replace("PAG", "").replace("Img2ImgPipeline", "PAGImg2ImgPipeline"),
|
| 811 |
+
)
|
| 812 |
+
else:
|
| 813 |
+
image_2_image_cls = _get_task_class(
|
| 814 |
+
AUTO_IMAGE2IMAGE_PIPELINES_MAPPING,
|
| 815 |
+
image_2_image_cls.__name__.replace("PAG", ""),
|
| 816 |
+
)
|
| 817 |
+
|
| 818 |
+
# define expected module and optional kwargs given the pipeline signature
|
| 819 |
+
expected_modules, optional_kwargs = image_2_image_cls._get_signature_keys(image_2_image_cls)
|
| 820 |
+
|
| 821 |
+
pretrained_model_name_or_path = original_config.pop("_name_or_path", None)
|
| 822 |
+
|
| 823 |
+
# allow users pass modules in `kwargs` to override the original pipeline's components
|
| 824 |
+
passed_class_obj = {k: kwargs.pop(k) for k in expected_modules if k in kwargs}
|
| 825 |
+
original_class_obj = {
|
| 826 |
+
k: pipeline.components[k]
|
| 827 |
+
for k, v in pipeline.components.items()
|
| 828 |
+
if k in expected_modules and k not in passed_class_obj
|
| 829 |
+
}
|
| 830 |
+
|
| 831 |
+
# allow users pass optional kwargs to override the original pipelines config attribute
|
| 832 |
+
passed_pipe_kwargs = {k: kwargs.pop(k) for k in optional_kwargs if k in kwargs}
|
| 833 |
+
original_pipe_kwargs = {
|
| 834 |
+
k: original_config[k]
|
| 835 |
+
for k, v in original_config.items()
|
| 836 |
+
if k in optional_kwargs and k not in passed_pipe_kwargs
|
| 837 |
+
}
|
| 838 |
+
|
| 839 |
+
# config attribute that were not expected by original pipeline is stored as its private attribute
|
| 840 |
+
# we will pass them as optional arguments if they can be accepted by the pipeline
|
| 841 |
+
additional_pipe_kwargs = [
|
| 842 |
+
k[1:]
|
| 843 |
+
for k in original_config.keys()
|
| 844 |
+
if k.startswith("_") and k[1:] in optional_kwargs and k[1:] not in passed_pipe_kwargs
|
| 845 |
+
]
|
| 846 |
+
for k in additional_pipe_kwargs:
|
| 847 |
+
original_pipe_kwargs[k] = original_config.pop(f"_{k}")
|
| 848 |
+
|
| 849 |
+
image_2_image_kwargs = {**passed_class_obj, **original_class_obj, **passed_pipe_kwargs, **original_pipe_kwargs}
|
| 850 |
+
|
| 851 |
+
# store unused config as private attribute
|
| 852 |
+
unused_original_config = {
|
| 853 |
+
f"{'' if k.startswith('_') else '_'}{k}": original_config[k]
|
| 854 |
+
for k, v in original_config.items()
|
| 855 |
+
if k not in image_2_image_kwargs
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
+
missing_modules = (
|
| 859 |
+
set(expected_modules) - set(image_2_image_cls._optional_components) - set(image_2_image_kwargs.keys())
|
| 860 |
+
)
|
| 861 |
+
|
| 862 |
+
if len(missing_modules) > 0:
|
| 863 |
+
raise ValueError(
|
| 864 |
+
f"Pipeline {image_2_image_cls} expected {expected_modules}, but only {set(list(passed_class_obj.keys()) + list(original_class_obj.keys()))} were passed"
|
| 865 |
+
)
|
| 866 |
+
|
| 867 |
+
model = image_2_image_cls(**image_2_image_kwargs)
|
| 868 |
+
model.register_to_config(_name_or_path=pretrained_model_name_or_path)
|
| 869 |
+
model.register_to_config(**unused_original_config)
|
| 870 |
+
|
| 871 |
+
return model
|
| 872 |
+
|
| 873 |
+
|
| 874 |
+
class AutoPipelineForInpainting(ConfigMixin):
|
| 875 |
+
r"""
|
| 876 |
+
|
| 877 |
+
[`AutoPipelineForInpainting`] is a generic pipeline class that instantiates an inpainting pipeline class. The
|
| 878 |
+
specific underlying pipeline class is automatically selected from either the
|
| 879 |
+
[`~AutoPipelineForInpainting.from_pretrained`] or [`~AutoPipelineForInpainting.from_pipe`] methods.
|
| 880 |
+
|
| 881 |
+
This class cannot be instantiated using `__init__()` (throws an error).
|
| 882 |
+
|
| 883 |
+
Class attributes:
|
| 884 |
+
|
| 885 |
+
- **config_name** (`str`) -- The configuration filename that stores the class and module names of all the
|
| 886 |
+
diffusion pipeline's components.
|
| 887 |
+
|
| 888 |
+
"""
|
| 889 |
+
|
| 890 |
+
config_name = "model_index.json"
|
| 891 |
+
|
| 892 |
+
def __init__(self, *args, **kwargs):
|
| 893 |
+
raise EnvironmentError(
|
| 894 |
+
f"{self.__class__.__name__} is designed to be instantiated "
|
| 895 |
+
f"using the `{self.__class__.__name__}.from_pretrained(pretrained_model_name_or_path)` or "
|
| 896 |
+
f"`{self.__class__.__name__}.from_pipe(pipeline)` methods."
|
| 897 |
+
)
|
| 898 |
+
|
| 899 |
+
@classmethod
|
| 900 |
+
@validate_hf_hub_args
|
| 901 |
+
def from_pretrained(cls, pretrained_model_or_path, **kwargs):
|
| 902 |
+
r"""
|
| 903 |
+
Instantiates a inpainting Pytorch diffusion pipeline from pretrained pipeline weight.
|
| 904 |
+
|
| 905 |
+
The from_pretrained() method takes care of returning the correct pipeline class instance by:
|
| 906 |
+
1. Detect the pipeline class of the pretrained_model_or_path based on the _class_name property of its
|
| 907 |
+
config object
|
| 908 |
+
2. Find the inpainting pipeline linked to the pipeline class using pattern matching on pipeline class name.
|
| 909 |
+
|
| 910 |
+
If a `controlnet` argument is passed, it will instantiate a [`StableDiffusionControlNetInpaintPipeline`]
|
| 911 |
+
object.
|
| 912 |
+
|
| 913 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 914 |
+
|
| 915 |
+
If you get the error message below, you need to finetune the weights for your downstream task:
|
| 916 |
+
|
| 917 |
+
```
|
| 918 |
+
Some weights of UNet2DConditionModel were not initialized from the model checkpoint at stable-diffusion-v1-5/stable-diffusion-v1-5 and are newly initialized because the shapes did not match:
|
| 919 |
+
- conv_in.weight: found shape torch.Size([320, 4, 3, 3]) in the checkpoint and torch.Size([320, 9, 3, 3]) in the model instantiated
|
| 920 |
+
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
|
| 921 |
+
```
|
| 922 |
+
|
| 923 |
+
Parameters:
|
| 924 |
+
pretrained_model_or_path (`str` or `os.PathLike`, *optional*):
|
| 925 |
+
Can be either:
|
| 926 |
+
|
| 927 |
+
- A string, the *repo id* (for example `CompVis/ldm-text2im-large-256`) of a pretrained pipeline
|
| 928 |
+
hosted on the Hub.
|
| 929 |
+
- A path to a *directory* (for example `./my_pipeline_directory/`) containing pipeline weights
|
| 930 |
+
saved using
|
| 931 |
+
[`~DiffusionPipeline.save_pretrained`].
|
| 932 |
+
torch_dtype (`str` or `torch.dtype`, *optional*):
|
| 933 |
+
Override the default `torch.dtype` and load the model with another dtype.
|
| 934 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 935 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 936 |
+
cached versions if they exist.
|
| 937 |
+
cache_dir (`Union[str, os.PathLike]`, *optional*):
|
| 938 |
+
Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
|
| 939 |
+
is not used.
|
| 940 |
+
|
| 941 |
+
proxies (`Dict[str, str]`, *optional*):
|
| 942 |
+
A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
|
| 943 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 944 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 945 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 946 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 947 |
+
Whether to only load local model weights and configuration files or not. If set to `True`, the model
|
| 948 |
+
won't be downloaded from the Hub.
|
| 949 |
+
token (`str` or *bool*, *optional*):
|
| 950 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
|
| 951 |
+
`diffusers-cli login` (stored in `~/.huggingface`) is used.
|
| 952 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 953 |
+
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
| 954 |
+
allowed by Git.
|
| 955 |
+
custom_revision (`str`, *optional*, defaults to `"main"`):
|
| 956 |
+
The specific model version to use. It can be a branch name, a tag name, or a commit id similar to
|
| 957 |
+
`revision` when loading a custom pipeline from the Hub. It can be a 🤗 Diffusers version when loading a
|
| 958 |
+
custom pipeline from GitHub, otherwise it defaults to `"main"` when loading from the Hub.
|
| 959 |
+
mirror (`str`, *optional*):
|
| 960 |
+
Mirror source to resolve accessibility issues if you’re downloading a model in China. We do not
|
| 961 |
+
guarantee the timeliness or safety of the source, and you should refer to the mirror site for more
|
| 962 |
+
information.
|
| 963 |
+
device_map (`str` or `Dict[str, Union[int, str, torch.device]]`, *optional*):
|
| 964 |
+
A map that specifies where each submodule should go. It doesn’t need to be defined for each
|
| 965 |
+
parameter/buffer name; once a given module name is inside, every submodule of it will be sent to the
|
| 966 |
+
same device.
|
| 967 |
+
|
| 968 |
+
Set `device_map="auto"` to have 🤗 Accelerate automatically compute the most optimized `device_map`. For
|
| 969 |
+
more information about each option see [designing a device
|
| 970 |
+
map](https://hf.co/docs/accelerate/main/en/usage_guides/big_modeling#designing-a-device-map).
|
| 971 |
+
max_memory (`Dict`, *optional*):
|
| 972 |
+
A dictionary device identifier for the maximum memory. Will default to the maximum memory available for
|
| 973 |
+
each GPU and the available CPU RAM if unset.
|
| 974 |
+
offload_folder (`str` or `os.PathLike`, *optional*):
|
| 975 |
+
The path to offload weights if device_map contains the value `"disk"`.
|
| 976 |
+
offload_state_dict (`bool`, *optional*):
|
| 977 |
+
If `True`, temporarily offloads the CPU state dict to the hard drive to avoid running out of CPU RAM if
|
| 978 |
+
the weight of the CPU state dict + the biggest shard of the checkpoint does not fit. Defaults to `True`
|
| 979 |
+
when there is some disk offload.
|
| 980 |
+
low_cpu_mem_usage (`bool`, *optional*, defaults to `True` if torch version >= 1.9.0 else `False`):
|
| 981 |
+
Speed up model loading only loading the pretrained weights and not initializing the weights. This also
|
| 982 |
+
tries to not use more than 1x model size in CPU memory (including peak memory) while loading the model.
|
| 983 |
+
Only supported for PyTorch >= 1.9.0. If you are using an older version of PyTorch, setting this
|
| 984 |
+
argument to `True` will raise an error.
|
| 985 |
+
use_safetensors (`bool`, *optional*, defaults to `None`):
|
| 986 |
+
If set to `None`, the safetensors weights are downloaded if they're available **and** if the
|
| 987 |
+
safetensors library is installed. If set to `True`, the model is forcibly loaded from safetensors
|
| 988 |
+
weights. If set to `False`, safetensors weights are not loaded.
|
| 989 |
+
kwargs (remaining dictionary of keyword arguments, *optional*):
|
| 990 |
+
Can be used to overwrite load and saveable variables (the pipeline components of the specific pipeline
|
| 991 |
+
class). The overwritten components are passed directly to the pipelines `__init__` method. See example
|
| 992 |
+
below for more information.
|
| 993 |
+
variant (`str`, *optional*):
|
| 994 |
+
Load weights from a specified variant filename such as `"fp16"` or `"ema"`. This is ignored when
|
| 995 |
+
loading `from_flax`.
|
| 996 |
+
|
| 997 |
+
<Tip>
|
| 998 |
+
|
| 999 |
+
To use private or [gated](https://huggingface.co/docs/hub/models-gated#gated-models) models, log-in with
|
| 1000 |
+
`huggingface-cli login`.
|
| 1001 |
+
|
| 1002 |
+
</Tip>
|
| 1003 |
+
|
| 1004 |
+
Examples:
|
| 1005 |
+
|
| 1006 |
+
```py
|
| 1007 |
+
>>> from diffusers import AutoPipelineForInpainting
|
| 1008 |
+
|
| 1009 |
+
>>> pipeline = AutoPipelineForInpainting.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5")
|
| 1010 |
+
>>> image = pipeline(prompt, image=init_image, mask_image=mask_image).images[0]
|
| 1011 |
+
```
|
| 1012 |
+
"""
|
| 1013 |
+
cache_dir = kwargs.pop("cache_dir", None)
|
| 1014 |
+
force_download = kwargs.pop("force_download", False)
|
| 1015 |
+
proxies = kwargs.pop("proxies", None)
|
| 1016 |
+
token = kwargs.pop("token", None)
|
| 1017 |
+
local_files_only = kwargs.pop("local_files_only", False)
|
| 1018 |
+
revision = kwargs.pop("revision", None)
|
| 1019 |
+
|
| 1020 |
+
load_config_kwargs = {
|
| 1021 |
+
"cache_dir": cache_dir,
|
| 1022 |
+
"force_download": force_download,
|
| 1023 |
+
"proxies": proxies,
|
| 1024 |
+
"token": token,
|
| 1025 |
+
"local_files_only": local_files_only,
|
| 1026 |
+
"revision": revision,
|
| 1027 |
+
}
|
| 1028 |
+
|
| 1029 |
+
config = cls.load_config(pretrained_model_or_path, **load_config_kwargs)
|
| 1030 |
+
orig_class_name = config["_class_name"]
|
| 1031 |
+
|
| 1032 |
+
# The `orig_class_name`` can be:
|
| 1033 |
+
# `- *InpaintPipeline` (for inpaint-specific checkpoint)
|
| 1034 |
+
# - `*ControlPipeline` (for Flux tools specific checkpoint)
|
| 1035 |
+
# - or *Pipeline (for regular text-to-image checkpoint)
|
| 1036 |
+
if "Inpaint" in orig_class_name:
|
| 1037 |
+
to_replace = "InpaintPipeline"
|
| 1038 |
+
elif "ControlPipeline" in orig_class_name:
|
| 1039 |
+
to_replace = "ControlPipeline"
|
| 1040 |
+
else:
|
| 1041 |
+
to_replace = "Pipeline"
|
| 1042 |
+
|
| 1043 |
+
if "controlnet" in kwargs:
|
| 1044 |
+
if isinstance(kwargs["controlnet"], ControlNetUnionModel):
|
| 1045 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlNetUnion" + to_replace)
|
| 1046 |
+
else:
|
| 1047 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlNet" + to_replace)
|
| 1048 |
+
if "enable_pag" in kwargs:
|
| 1049 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 1050 |
+
if enable_pag:
|
| 1051 |
+
orig_class_name = orig_class_name.replace(to_replace, "PAG" + to_replace)
|
| 1052 |
+
if to_replace == "ControlPipeline":
|
| 1053 |
+
orig_class_name = orig_class_name.replace(to_replace, "ControlInpaintPipeline")
|
| 1054 |
+
inpainting_cls = _get_task_class(AUTO_INPAINT_PIPELINES_MAPPING, orig_class_name)
|
| 1055 |
+
|
| 1056 |
+
kwargs = {**load_config_kwargs, **kwargs}
|
| 1057 |
+
return inpainting_cls.from_pretrained(pretrained_model_or_path, **kwargs)
|
| 1058 |
+
|
| 1059 |
+
@classmethod
|
| 1060 |
+
def from_pipe(cls, pipeline, **kwargs):
|
| 1061 |
+
r"""
|
| 1062 |
+
Instantiates a inpainting Pytorch diffusion pipeline from another instantiated diffusion pipeline class.
|
| 1063 |
+
|
| 1064 |
+
The from_pipe() method takes care of returning the correct pipeline class instance by finding the inpainting
|
| 1065 |
+
pipeline linked to the pipeline class using pattern matching on pipeline class name.
|
| 1066 |
+
|
| 1067 |
+
All the modules the pipeline class contain will be used to initialize the new pipeline without reallocating
|
| 1068 |
+
additional memory.
|
| 1069 |
+
|
| 1070 |
+
The pipeline is set in evaluation mode (`model.eval()`) by default.
|
| 1071 |
+
|
| 1072 |
+
Parameters:
|
| 1073 |
+
pipeline (`DiffusionPipeline`):
|
| 1074 |
+
an instantiated `DiffusionPipeline` object
|
| 1075 |
+
|
| 1076 |
+
Examples:
|
| 1077 |
+
|
| 1078 |
+
```py
|
| 1079 |
+
>>> from diffusers import AutoPipelineForText2Image, AutoPipelineForInpainting
|
| 1080 |
+
|
| 1081 |
+
>>> pipe_t2i = AutoPipelineForText2Image.from_pretrained(
|
| 1082 |
+
... "DeepFloyd/IF-I-XL-v1.0", requires_safety_checker=False
|
| 1083 |
+
... )
|
| 1084 |
+
|
| 1085 |
+
>>> pipe_inpaint = AutoPipelineForInpainting.from_pipe(pipe_t2i)
|
| 1086 |
+
>>> image = pipe_inpaint(prompt, image=init_image, mask_image=mask_image).images[0]
|
| 1087 |
+
```
|
| 1088 |
+
"""
|
| 1089 |
+
original_config = dict(pipeline.config)
|
| 1090 |
+
original_cls_name = pipeline.__class__.__name__
|
| 1091 |
+
|
| 1092 |
+
# derive the pipeline class to instantiate
|
| 1093 |
+
inpainting_cls = _get_task_class(AUTO_INPAINT_PIPELINES_MAPPING, original_cls_name)
|
| 1094 |
+
|
| 1095 |
+
if "controlnet" in kwargs:
|
| 1096 |
+
if kwargs["controlnet"] is not None:
|
| 1097 |
+
inpainting_cls = _get_task_class(
|
| 1098 |
+
AUTO_INPAINT_PIPELINES_MAPPING,
|
| 1099 |
+
inpainting_cls.__name__.replace("ControlNet", "").replace(
|
| 1100 |
+
"InpaintPipeline", "ControlNetInpaintPipeline"
|
| 1101 |
+
),
|
| 1102 |
+
)
|
| 1103 |
+
else:
|
| 1104 |
+
inpainting_cls = _get_task_class(
|
| 1105 |
+
AUTO_INPAINT_PIPELINES_MAPPING,
|
| 1106 |
+
inpainting_cls.__name__.replace("ControlNetInpaintPipeline", "InpaintPipeline"),
|
| 1107 |
+
)
|
| 1108 |
+
|
| 1109 |
+
if "enable_pag" in kwargs:
|
| 1110 |
+
enable_pag = kwargs.pop("enable_pag")
|
| 1111 |
+
if enable_pag:
|
| 1112 |
+
inpainting_cls = _get_task_class(
|
| 1113 |
+
AUTO_INPAINT_PIPELINES_MAPPING,
|
| 1114 |
+
inpainting_cls.__name__.replace("PAG", "").replace("InpaintPipeline", "PAGInpaintPipeline"),
|
| 1115 |
+
)
|
| 1116 |
+
else:
|
| 1117 |
+
inpainting_cls = _get_task_class(
|
| 1118 |
+
AUTO_INPAINT_PIPELINES_MAPPING,
|
| 1119 |
+
inpainting_cls.__name__.replace("PAGInpaintPipeline", "InpaintPipeline"),
|
| 1120 |
+
)
|
| 1121 |
+
|
| 1122 |
+
# define expected module and optional kwargs given the pipeline signature
|
| 1123 |
+
expected_modules, optional_kwargs = inpainting_cls._get_signature_keys(inpainting_cls)
|
| 1124 |
+
|
| 1125 |
+
pretrained_model_name_or_path = original_config.pop("_name_or_path", None)
|
| 1126 |
+
|
| 1127 |
+
# allow users pass modules in `kwargs` to override the original pipeline's components
|
| 1128 |
+
passed_class_obj = {k: kwargs.pop(k) for k in expected_modules if k in kwargs}
|
| 1129 |
+
original_class_obj = {
|
| 1130 |
+
k: pipeline.components[k]
|
| 1131 |
+
for k, v in pipeline.components.items()
|
| 1132 |
+
if k in expected_modules and k not in passed_class_obj
|
| 1133 |
+
}
|
| 1134 |
+
|
| 1135 |
+
# allow users pass optional kwargs to override the original pipelines config attribute
|
| 1136 |
+
passed_pipe_kwargs = {k: kwargs.pop(k) for k in optional_kwargs if k in kwargs}
|
| 1137 |
+
original_pipe_kwargs = {
|
| 1138 |
+
k: original_config[k]
|
| 1139 |
+
for k, v in original_config.items()
|
| 1140 |
+
if k in optional_kwargs and k not in passed_pipe_kwargs
|
| 1141 |
+
}
|
| 1142 |
+
|
| 1143 |
+
# config that were not expected by original pipeline is stored as private attribute
|
| 1144 |
+
# we will pass them as optional arguments if they can be accepted by the pipeline
|
| 1145 |
+
additional_pipe_kwargs = [
|
| 1146 |
+
k[1:]
|
| 1147 |
+
for k in original_config.keys()
|
| 1148 |
+
if k.startswith("_") and k[1:] in optional_kwargs and k[1:] not in passed_pipe_kwargs
|
| 1149 |
+
]
|
| 1150 |
+
for k in additional_pipe_kwargs:
|
| 1151 |
+
original_pipe_kwargs[k] = original_config.pop(f"_{k}")
|
| 1152 |
+
|
| 1153 |
+
inpainting_kwargs = {**passed_class_obj, **original_class_obj, **passed_pipe_kwargs, **original_pipe_kwargs}
|
| 1154 |
+
|
| 1155 |
+
# store unused config as private attribute
|
| 1156 |
+
unused_original_config = {
|
| 1157 |
+
f"{'' if k.startswith('_') else '_'}{k}": original_config[k]
|
| 1158 |
+
for k, v in original_config.items()
|
| 1159 |
+
if k not in inpainting_kwargs
|
| 1160 |
+
}
|
| 1161 |
+
|
| 1162 |
+
missing_modules = (
|
| 1163 |
+
set(expected_modules) - set(inpainting_cls._optional_components) - set(inpainting_kwargs.keys())
|
| 1164 |
+
)
|
| 1165 |
+
|
| 1166 |
+
if len(missing_modules) > 0:
|
| 1167 |
+
raise ValueError(
|
| 1168 |
+
f"Pipeline {inpainting_cls} expected {expected_modules}, but only {set(list(passed_class_obj.keys()) + list(original_class_obj.keys()))} were passed"
|
| 1169 |
+
)
|
| 1170 |
+
|
| 1171 |
+
model = inpainting_cls(**inpainting_kwargs)
|
| 1172 |
+
model.register_to_config(_name_or_path=pretrained_model_name_or_path)
|
| 1173 |
+
model.register_to_config(**unused_original_config)
|
| 1174 |
+
|
| 1175 |
+
return model
|
venv/lib/python3.10/site-packages/diffusers/pipelines/free_init_utils.py
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
| 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 at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# 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 and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import math
|
| 16 |
+
from typing import Tuple, Union
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
import torch.fft as fft
|
| 20 |
+
|
| 21 |
+
from ..utils.torch_utils import randn_tensor
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class FreeInitMixin:
|
| 25 |
+
r"""Mixin class for FreeInit."""
|
| 26 |
+
|
| 27 |
+
def enable_free_init(
|
| 28 |
+
self,
|
| 29 |
+
num_iters: int = 3,
|
| 30 |
+
use_fast_sampling: bool = False,
|
| 31 |
+
method: str = "butterworth",
|
| 32 |
+
order: int = 4,
|
| 33 |
+
spatial_stop_frequency: float = 0.25,
|
| 34 |
+
temporal_stop_frequency: float = 0.25,
|
| 35 |
+
):
|
| 36 |
+
"""Enables the FreeInit mechanism as in https://huggingface.co/papers/2312.07537.
|
| 37 |
+
|
| 38 |
+
This implementation has been adapted from the [official repository](https://github.com/TianxingWu/FreeInit).
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
num_iters (`int`, *optional*, defaults to `3`):
|
| 42 |
+
Number of FreeInit noise re-initialization iterations.
|
| 43 |
+
use_fast_sampling (`bool`, *optional*, defaults to `False`):
|
| 44 |
+
Whether or not to speedup sampling procedure at the cost of probably lower quality results. Enables the
|
| 45 |
+
"Coarse-to-Fine Sampling" strategy, as mentioned in the paper, if set to `True`.
|
| 46 |
+
method (`str`, *optional*, defaults to `butterworth`):
|
| 47 |
+
Must be one of `butterworth`, `ideal` or `gaussian` to use as the filtering method for the FreeInit low
|
| 48 |
+
pass filter.
|
| 49 |
+
order (`int`, *optional*, defaults to `4`):
|
| 50 |
+
Order of the filter used in `butterworth` method. Larger values lead to `ideal` method behaviour
|
| 51 |
+
whereas lower values lead to `gaussian` method behaviour.
|
| 52 |
+
spatial_stop_frequency (`float`, *optional*, defaults to `0.25`):
|
| 53 |
+
Normalized stop frequency for spatial dimensions. Must be between 0 to 1. Referred to as `d_s` in the
|
| 54 |
+
original implementation.
|
| 55 |
+
temporal_stop_frequency (`float`, *optional*, defaults to `0.25`):
|
| 56 |
+
Normalized stop frequency for temporal dimensions. Must be between 0 to 1. Referred to as `d_t` in the
|
| 57 |
+
original implementation.
|
| 58 |
+
"""
|
| 59 |
+
self._free_init_num_iters = num_iters
|
| 60 |
+
self._free_init_use_fast_sampling = use_fast_sampling
|
| 61 |
+
self._free_init_method = method
|
| 62 |
+
self._free_init_order = order
|
| 63 |
+
self._free_init_spatial_stop_frequency = spatial_stop_frequency
|
| 64 |
+
self._free_init_temporal_stop_frequency = temporal_stop_frequency
|
| 65 |
+
|
| 66 |
+
def disable_free_init(self):
|
| 67 |
+
"""Disables the FreeInit mechanism if enabled."""
|
| 68 |
+
self._free_init_num_iters = None
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def free_init_enabled(self):
|
| 72 |
+
return hasattr(self, "_free_init_num_iters") and self._free_init_num_iters is not None
|
| 73 |
+
|
| 74 |
+
def _get_free_init_freq_filter(
|
| 75 |
+
self,
|
| 76 |
+
shape: Tuple[int, ...],
|
| 77 |
+
device: Union[str, torch.dtype],
|
| 78 |
+
filter_type: str,
|
| 79 |
+
order: float,
|
| 80 |
+
spatial_stop_frequency: float,
|
| 81 |
+
temporal_stop_frequency: float,
|
| 82 |
+
) -> torch.Tensor:
|
| 83 |
+
r"""Returns the FreeInit filter based on filter type and other input conditions."""
|
| 84 |
+
|
| 85 |
+
time, height, width = shape[-3], shape[-2], shape[-1]
|
| 86 |
+
mask = torch.zeros(shape)
|
| 87 |
+
|
| 88 |
+
if spatial_stop_frequency == 0 or temporal_stop_frequency == 0:
|
| 89 |
+
return mask
|
| 90 |
+
|
| 91 |
+
if filter_type == "butterworth":
|
| 92 |
+
|
| 93 |
+
def retrieve_mask(x):
|
| 94 |
+
return 1 / (1 + (x / spatial_stop_frequency**2) ** order)
|
| 95 |
+
elif filter_type == "gaussian":
|
| 96 |
+
|
| 97 |
+
def retrieve_mask(x):
|
| 98 |
+
return math.exp(-1 / (2 * spatial_stop_frequency**2) * x)
|
| 99 |
+
elif filter_type == "ideal":
|
| 100 |
+
|
| 101 |
+
def retrieve_mask(x):
|
| 102 |
+
return 1 if x <= spatial_stop_frequency * 2 else 0
|
| 103 |
+
else:
|
| 104 |
+
raise NotImplementedError("`filter_type` must be one of gaussian, butterworth or ideal")
|
| 105 |
+
|
| 106 |
+
for t in range(time):
|
| 107 |
+
for h in range(height):
|
| 108 |
+
for w in range(width):
|
| 109 |
+
d_square = (
|
| 110 |
+
((spatial_stop_frequency / temporal_stop_frequency) * (2 * t / time - 1)) ** 2
|
| 111 |
+
+ (2 * h / height - 1) ** 2
|
| 112 |
+
+ (2 * w / width - 1) ** 2
|
| 113 |
+
)
|
| 114 |
+
mask[..., t, h, w] = retrieve_mask(d_square)
|
| 115 |
+
|
| 116 |
+
return mask.to(device)
|
| 117 |
+
|
| 118 |
+
def _apply_freq_filter(self, x: torch.Tensor, noise: torch.Tensor, low_pass_filter: torch.Tensor) -> torch.Tensor:
|
| 119 |
+
r"""Noise reinitialization."""
|
| 120 |
+
# FFT
|
| 121 |
+
x_freq = fft.fftn(x, dim=(-3, -2, -1))
|
| 122 |
+
x_freq = fft.fftshift(x_freq, dim=(-3, -2, -1))
|
| 123 |
+
noise_freq = fft.fftn(noise, dim=(-3, -2, -1))
|
| 124 |
+
noise_freq = fft.fftshift(noise_freq, dim=(-3, -2, -1))
|
| 125 |
+
|
| 126 |
+
# frequency mix
|
| 127 |
+
high_pass_filter = 1 - low_pass_filter
|
| 128 |
+
x_freq_low = x_freq * low_pass_filter
|
| 129 |
+
noise_freq_high = noise_freq * high_pass_filter
|
| 130 |
+
x_freq_mixed = x_freq_low + noise_freq_high # mix in freq domain
|
| 131 |
+
|
| 132 |
+
# IFFT
|
| 133 |
+
x_freq_mixed = fft.ifftshift(x_freq_mixed, dim=(-3, -2, -1))
|
| 134 |
+
x_mixed = fft.ifftn(x_freq_mixed, dim=(-3, -2, -1)).real
|
| 135 |
+
|
| 136 |
+
return x_mixed
|
| 137 |
+
|
| 138 |
+
def _apply_free_init(
|
| 139 |
+
self,
|
| 140 |
+
latents: torch.Tensor,
|
| 141 |
+
free_init_iteration: int,
|
| 142 |
+
num_inference_steps: int,
|
| 143 |
+
device: torch.device,
|
| 144 |
+
dtype: torch.dtype,
|
| 145 |
+
generator: torch.Generator,
|
| 146 |
+
):
|
| 147 |
+
if free_init_iteration == 0:
|
| 148 |
+
self._free_init_initial_noise = latents.detach().clone()
|
| 149 |
+
else:
|
| 150 |
+
latent_shape = latents.shape
|
| 151 |
+
|
| 152 |
+
free_init_filter_shape = (1, *latent_shape[1:])
|
| 153 |
+
free_init_freq_filter = self._get_free_init_freq_filter(
|
| 154 |
+
shape=free_init_filter_shape,
|
| 155 |
+
device=device,
|
| 156 |
+
filter_type=self._free_init_method,
|
| 157 |
+
order=self._free_init_order,
|
| 158 |
+
spatial_stop_frequency=self._free_init_spatial_stop_frequency,
|
| 159 |
+
temporal_stop_frequency=self._free_init_temporal_stop_frequency,
|
| 160 |
+
)
|
| 161 |
+
|
| 162 |
+
current_diffuse_timestep = self.scheduler.config.num_train_timesteps - 1
|
| 163 |
+
diffuse_timesteps = torch.full((latent_shape[0],), current_diffuse_timestep).long()
|
| 164 |
+
|
| 165 |
+
z_t = self.scheduler.add_noise(
|
| 166 |
+
original_samples=latents, noise=self._free_init_initial_noise, timesteps=diffuse_timesteps.to(device)
|
| 167 |
+
).to(dtype=torch.float32)
|
| 168 |
+
|
| 169 |
+
z_rand = randn_tensor(
|
| 170 |
+
shape=latent_shape,
|
| 171 |
+
generator=generator,
|
| 172 |
+
device=device,
|
| 173 |
+
dtype=torch.float32,
|
| 174 |
+
)
|
| 175 |
+
latents = self._apply_freq_filter(z_t, z_rand, low_pass_filter=free_init_freq_filter)
|
| 176 |
+
latents = latents.to(dtype)
|
| 177 |
+
|
| 178 |
+
# Coarse-to-Fine Sampling for faster inference (can lead to lower quality)
|
| 179 |
+
if self._free_init_use_fast_sampling:
|
| 180 |
+
num_inference_steps = max(
|
| 181 |
+
1, int(num_inference_steps / self._free_init_num_iters * (free_init_iteration + 1))
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
if num_inference_steps > 0:
|
| 185 |
+
self.scheduler.set_timesteps(num_inference_steps, device=device)
|
| 186 |
+
|
| 187 |
+
return latents, self.scheduler.timesteps
|
venv/lib/python3.10/site-packages/diffusers/pipelines/free_noise_utils.py
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2025 The HuggingFace Team. All rights reserved.
|
| 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 at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# 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 and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
from typing import Callable, Dict, List, Optional, Tuple, Union
|
| 16 |
+
|
| 17 |
+
import torch
|
| 18 |
+
import torch.nn as nn
|
| 19 |
+
|
| 20 |
+
from ..models.attention import BasicTransformerBlock, FreeNoiseTransformerBlock
|
| 21 |
+
from ..models.resnet import Downsample2D, ResnetBlock2D, Upsample2D
|
| 22 |
+
from ..models.transformers.transformer_2d import Transformer2DModel
|
| 23 |
+
from ..models.unets.unet_motion_model import (
|
| 24 |
+
AnimateDiffTransformer3D,
|
| 25 |
+
CrossAttnDownBlockMotion,
|
| 26 |
+
DownBlockMotion,
|
| 27 |
+
UpBlockMotion,
|
| 28 |
+
)
|
| 29 |
+
from ..pipelines.pipeline_utils import DiffusionPipeline
|
| 30 |
+
from ..utils import logging
|
| 31 |
+
from ..utils.torch_utils import randn_tensor
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
logger = logging.get_logger(__name__) # pylint: disable=invalid-name
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class SplitInferenceModule(nn.Module):
|
| 38 |
+
r"""
|
| 39 |
+
A wrapper module class that splits inputs along a specified dimension before performing a forward pass.
|
| 40 |
+
|
| 41 |
+
This module is useful when you need to perform inference on large tensors in a memory-efficient way by breaking
|
| 42 |
+
them into smaller chunks, processing each chunk separately, and then reassembling the results.
|
| 43 |
+
|
| 44 |
+
Args:
|
| 45 |
+
module (`nn.Module`):
|
| 46 |
+
The underlying PyTorch module that will be applied to each chunk of split inputs.
|
| 47 |
+
split_size (`int`, defaults to `1`):
|
| 48 |
+
The size of each chunk after splitting the input tensor.
|
| 49 |
+
split_dim (`int`, defaults to `0`):
|
| 50 |
+
The dimension along which the input tensors are split.
|
| 51 |
+
input_kwargs_to_split (`List[str]`, defaults to `["hidden_states"]`):
|
| 52 |
+
A list of keyword arguments (strings) that represent the input tensors to be split.
|
| 53 |
+
|
| 54 |
+
Workflow:
|
| 55 |
+
1. The keyword arguments specified in `input_kwargs_to_split` are split into smaller chunks using
|
| 56 |
+
`torch.split()` along the dimension `split_dim` and with a chunk size of `split_size`.
|
| 57 |
+
2. The `module` is invoked once for each split with both the split inputs and any unchanged arguments
|
| 58 |
+
that were passed.
|
| 59 |
+
3. The output tensors from each split are concatenated back together along `split_dim` before returning.
|
| 60 |
+
|
| 61 |
+
Example:
|
| 62 |
+
```python
|
| 63 |
+
>>> import torch
|
| 64 |
+
>>> import torch.nn as nn
|
| 65 |
+
|
| 66 |
+
>>> model = nn.Linear(1000, 1000)
|
| 67 |
+
>>> split_module = SplitInferenceModule(model, split_size=2, split_dim=0, input_kwargs_to_split=["input"])
|
| 68 |
+
|
| 69 |
+
>>> input_tensor = torch.randn(42, 1000)
|
| 70 |
+
>>> # Will split the tensor into 21 slices of shape [2, 1000].
|
| 71 |
+
>>> output = split_module(input=input_tensor)
|
| 72 |
+
```
|
| 73 |
+
|
| 74 |
+
It is also possible to nest `SplitInferenceModule` across different split dimensions for more complex
|
| 75 |
+
multi-dimensional splitting.
|
| 76 |
+
"""
|
| 77 |
+
|
| 78 |
+
def __init__(
|
| 79 |
+
self,
|
| 80 |
+
module: nn.Module,
|
| 81 |
+
split_size: int = 1,
|
| 82 |
+
split_dim: int = 0,
|
| 83 |
+
input_kwargs_to_split: List[str] = ["hidden_states"],
|
| 84 |
+
) -> None:
|
| 85 |
+
super().__init__()
|
| 86 |
+
|
| 87 |
+
self.module = module
|
| 88 |
+
self.split_size = split_size
|
| 89 |
+
self.split_dim = split_dim
|
| 90 |
+
self.input_kwargs_to_split = set(input_kwargs_to_split)
|
| 91 |
+
|
| 92 |
+
def forward(self, *args, **kwargs) -> Union[torch.Tensor, Tuple[torch.Tensor]]:
|
| 93 |
+
r"""Forward method for the `SplitInferenceModule`.
|
| 94 |
+
|
| 95 |
+
This method processes the input by splitting specified keyword arguments along a given dimension, running the
|
| 96 |
+
underlying module on each split, and then concatenating the results. The splitting is controlled by the
|
| 97 |
+
`split_size` and `split_dim` parameters specified during initialization.
|
| 98 |
+
|
| 99 |
+
Args:
|
| 100 |
+
*args (`Any`):
|
| 101 |
+
Positional arguments that are passed directly to the `module` without modification.
|
| 102 |
+
**kwargs (`Dict[str, torch.Tensor]`):
|
| 103 |
+
Keyword arguments passed to the underlying `module`. Only keyword arguments whose names match the
|
| 104 |
+
entries in `input_kwargs_to_split` and are of type `torch.Tensor` will be split. The remaining keyword
|
| 105 |
+
arguments are passed unchanged.
|
| 106 |
+
|
| 107 |
+
Returns:
|
| 108 |
+
`Union[torch.Tensor, Tuple[torch.Tensor]]`:
|
| 109 |
+
The outputs obtained from `SplitInferenceModule` are the same as if the underlying module was inferred
|
| 110 |
+
without it.
|
| 111 |
+
- If the underlying module returns a single tensor, the result will be a single concatenated tensor
|
| 112 |
+
along the same `split_dim` after processing all splits.
|
| 113 |
+
- If the underlying module returns a tuple of tensors, each element of the tuple will be concatenated
|
| 114 |
+
along the `split_dim` across all splits, and the final result will be a tuple of concatenated tensors.
|
| 115 |
+
"""
|
| 116 |
+
split_inputs = {}
|
| 117 |
+
|
| 118 |
+
# 1. Split inputs that were specified during initialization and also present in passed kwargs
|
| 119 |
+
for key in list(kwargs.keys()):
|
| 120 |
+
if key not in self.input_kwargs_to_split or not torch.is_tensor(kwargs[key]):
|
| 121 |
+
continue
|
| 122 |
+
split_inputs[key] = torch.split(kwargs[key], self.split_size, self.split_dim)
|
| 123 |
+
kwargs.pop(key)
|
| 124 |
+
|
| 125 |
+
# 2. Invoke forward pass across each split
|
| 126 |
+
results = []
|
| 127 |
+
for split_input in zip(*split_inputs.values()):
|
| 128 |
+
inputs = dict(zip(split_inputs.keys(), split_input))
|
| 129 |
+
inputs.update(kwargs)
|
| 130 |
+
|
| 131 |
+
intermediate_tensor_or_tensor_tuple = self.module(*args, **inputs)
|
| 132 |
+
results.append(intermediate_tensor_or_tensor_tuple)
|
| 133 |
+
|
| 134 |
+
# 3. Concatenate split restuls to obtain final outputs
|
| 135 |
+
if isinstance(results[0], torch.Tensor):
|
| 136 |
+
return torch.cat(results, dim=self.split_dim)
|
| 137 |
+
elif isinstance(results[0], tuple):
|
| 138 |
+
return tuple([torch.cat(x, dim=self.split_dim) for x in zip(*results)])
|
| 139 |
+
else:
|
| 140 |
+
raise ValueError(
|
| 141 |
+
"In order to use the SplitInferenceModule, it is necessary for the underlying `module` to either return a torch.Tensor or a tuple of torch.Tensor's."
|
| 142 |
+
)
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
class AnimateDiffFreeNoiseMixin:
|
| 146 |
+
r"""Mixin class for [FreeNoise](https://huggingface.co/papers/2310.15169)."""
|
| 147 |
+
|
| 148 |
+
def _enable_free_noise_in_block(self, block: Union[CrossAttnDownBlockMotion, DownBlockMotion, UpBlockMotion]):
|
| 149 |
+
r"""Helper function to enable FreeNoise in transformer blocks."""
|
| 150 |
+
|
| 151 |
+
for motion_module in block.motion_modules:
|
| 152 |
+
num_transformer_blocks = len(motion_module.transformer_blocks)
|
| 153 |
+
|
| 154 |
+
for i in range(num_transformer_blocks):
|
| 155 |
+
if isinstance(motion_module.transformer_blocks[i], FreeNoiseTransformerBlock):
|
| 156 |
+
motion_module.transformer_blocks[i].set_free_noise_properties(
|
| 157 |
+
self._free_noise_context_length,
|
| 158 |
+
self._free_noise_context_stride,
|
| 159 |
+
self._free_noise_weighting_scheme,
|
| 160 |
+
)
|
| 161 |
+
else:
|
| 162 |
+
assert isinstance(motion_module.transformer_blocks[i], BasicTransformerBlock)
|
| 163 |
+
basic_transfomer_block = motion_module.transformer_blocks[i]
|
| 164 |
+
|
| 165 |
+
motion_module.transformer_blocks[i] = FreeNoiseTransformerBlock(
|
| 166 |
+
dim=basic_transfomer_block.dim,
|
| 167 |
+
num_attention_heads=basic_transfomer_block.num_attention_heads,
|
| 168 |
+
attention_head_dim=basic_transfomer_block.attention_head_dim,
|
| 169 |
+
dropout=basic_transfomer_block.dropout,
|
| 170 |
+
cross_attention_dim=basic_transfomer_block.cross_attention_dim,
|
| 171 |
+
activation_fn=basic_transfomer_block.activation_fn,
|
| 172 |
+
attention_bias=basic_transfomer_block.attention_bias,
|
| 173 |
+
only_cross_attention=basic_transfomer_block.only_cross_attention,
|
| 174 |
+
double_self_attention=basic_transfomer_block.double_self_attention,
|
| 175 |
+
positional_embeddings=basic_transfomer_block.positional_embeddings,
|
| 176 |
+
num_positional_embeddings=basic_transfomer_block.num_positional_embeddings,
|
| 177 |
+
context_length=self._free_noise_context_length,
|
| 178 |
+
context_stride=self._free_noise_context_stride,
|
| 179 |
+
weighting_scheme=self._free_noise_weighting_scheme,
|
| 180 |
+
).to(device=self.device, dtype=self.dtype)
|
| 181 |
+
|
| 182 |
+
motion_module.transformer_blocks[i].load_state_dict(
|
| 183 |
+
basic_transfomer_block.state_dict(), strict=True
|
| 184 |
+
)
|
| 185 |
+
motion_module.transformer_blocks[i].set_chunk_feed_forward(
|
| 186 |
+
basic_transfomer_block._chunk_size, basic_transfomer_block._chunk_dim
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
def _disable_free_noise_in_block(self, block: Union[CrossAttnDownBlockMotion, DownBlockMotion, UpBlockMotion]):
|
| 190 |
+
r"""Helper function to disable FreeNoise in transformer blocks."""
|
| 191 |
+
|
| 192 |
+
for motion_module in block.motion_modules:
|
| 193 |
+
num_transformer_blocks = len(motion_module.transformer_blocks)
|
| 194 |
+
|
| 195 |
+
for i in range(num_transformer_blocks):
|
| 196 |
+
if isinstance(motion_module.transformer_blocks[i], FreeNoiseTransformerBlock):
|
| 197 |
+
free_noise_transfomer_block = motion_module.transformer_blocks[i]
|
| 198 |
+
|
| 199 |
+
motion_module.transformer_blocks[i] = BasicTransformerBlock(
|
| 200 |
+
dim=free_noise_transfomer_block.dim,
|
| 201 |
+
num_attention_heads=free_noise_transfomer_block.num_attention_heads,
|
| 202 |
+
attention_head_dim=free_noise_transfomer_block.attention_head_dim,
|
| 203 |
+
dropout=free_noise_transfomer_block.dropout,
|
| 204 |
+
cross_attention_dim=free_noise_transfomer_block.cross_attention_dim,
|
| 205 |
+
activation_fn=free_noise_transfomer_block.activation_fn,
|
| 206 |
+
attention_bias=free_noise_transfomer_block.attention_bias,
|
| 207 |
+
only_cross_attention=free_noise_transfomer_block.only_cross_attention,
|
| 208 |
+
double_self_attention=free_noise_transfomer_block.double_self_attention,
|
| 209 |
+
positional_embeddings=free_noise_transfomer_block.positional_embeddings,
|
| 210 |
+
num_positional_embeddings=free_noise_transfomer_block.num_positional_embeddings,
|
| 211 |
+
).to(device=self.device, dtype=self.dtype)
|
| 212 |
+
|
| 213 |
+
motion_module.transformer_blocks[i].load_state_dict(
|
| 214 |
+
free_noise_transfomer_block.state_dict(), strict=True
|
| 215 |
+
)
|
| 216 |
+
motion_module.transformer_blocks[i].set_chunk_feed_forward(
|
| 217 |
+
free_noise_transfomer_block._chunk_size, free_noise_transfomer_block._chunk_dim
|
| 218 |
+
)
|
| 219 |
+
|
| 220 |
+
def _check_inputs_free_noise(
|
| 221 |
+
self,
|
| 222 |
+
prompt,
|
| 223 |
+
negative_prompt,
|
| 224 |
+
prompt_embeds,
|
| 225 |
+
negative_prompt_embeds,
|
| 226 |
+
num_frames,
|
| 227 |
+
) -> None:
|
| 228 |
+
if not isinstance(prompt, (str, dict)):
|
| 229 |
+
raise ValueError(f"Expected `prompt` to have type `str` or `dict` but found {type(prompt)=}")
|
| 230 |
+
|
| 231 |
+
if negative_prompt is not None:
|
| 232 |
+
if not isinstance(negative_prompt, (str, dict)):
|
| 233 |
+
raise ValueError(
|
| 234 |
+
f"Expected `negative_prompt` to have type `str` or `dict` but found {type(negative_prompt)=}"
|
| 235 |
+
)
|
| 236 |
+
|
| 237 |
+
if prompt_embeds is not None or negative_prompt_embeds is not None:
|
| 238 |
+
raise ValueError("`prompt_embeds` and `negative_prompt_embeds` is not supported in FreeNoise yet.")
|
| 239 |
+
|
| 240 |
+
frame_indices = [isinstance(x, int) for x in prompt.keys()]
|
| 241 |
+
frame_prompts = [isinstance(x, str) for x in prompt.values()]
|
| 242 |
+
min_frame = min(list(prompt.keys()))
|
| 243 |
+
max_frame = max(list(prompt.keys()))
|
| 244 |
+
|
| 245 |
+
if not all(frame_indices):
|
| 246 |
+
raise ValueError("Expected integer keys in `prompt` dict for FreeNoise.")
|
| 247 |
+
if not all(frame_prompts):
|
| 248 |
+
raise ValueError("Expected str values in `prompt` dict for FreeNoise.")
|
| 249 |
+
if min_frame != 0:
|
| 250 |
+
raise ValueError("The minimum frame index in `prompt` dict must be 0 as a starting prompt is necessary.")
|
| 251 |
+
if max_frame >= num_frames:
|
| 252 |
+
raise ValueError(
|
| 253 |
+
f"The maximum frame index in `prompt` dict must be lesser than {num_frames=} and follow 0-based indexing."
|
| 254 |
+
)
|
| 255 |
+
|
| 256 |
+
def _encode_prompt_free_noise(
|
| 257 |
+
self,
|
| 258 |
+
prompt: Union[str, Dict[int, str]],
|
| 259 |
+
num_frames: int,
|
| 260 |
+
device: torch.device,
|
| 261 |
+
num_videos_per_prompt: int,
|
| 262 |
+
do_classifier_free_guidance: bool,
|
| 263 |
+
negative_prompt: Optional[Union[str, Dict[int, str]]] = None,
|
| 264 |
+
prompt_embeds: Optional[torch.Tensor] = None,
|
| 265 |
+
negative_prompt_embeds: Optional[torch.Tensor] = None,
|
| 266 |
+
lora_scale: Optional[float] = None,
|
| 267 |
+
clip_skip: Optional[int] = None,
|
| 268 |
+
) -> torch.Tensor:
|
| 269 |
+
if negative_prompt is None:
|
| 270 |
+
negative_prompt = ""
|
| 271 |
+
|
| 272 |
+
# Ensure that we have a dictionary of prompts
|
| 273 |
+
if isinstance(prompt, str):
|
| 274 |
+
prompt = {0: prompt}
|
| 275 |
+
if isinstance(negative_prompt, str):
|
| 276 |
+
negative_prompt = {0: negative_prompt}
|
| 277 |
+
|
| 278 |
+
self._check_inputs_free_noise(prompt, negative_prompt, prompt_embeds, negative_prompt_embeds, num_frames)
|
| 279 |
+
|
| 280 |
+
# Sort the prompts based on frame indices
|
| 281 |
+
prompt = dict(sorted(prompt.items()))
|
| 282 |
+
negative_prompt = dict(sorted(negative_prompt.items()))
|
| 283 |
+
|
| 284 |
+
# Ensure that we have a prompt for the last frame index
|
| 285 |
+
prompt[num_frames - 1] = prompt[list(prompt.keys())[-1]]
|
| 286 |
+
negative_prompt[num_frames - 1] = negative_prompt[list(negative_prompt.keys())[-1]]
|
| 287 |
+
|
| 288 |
+
frame_indices = list(prompt.keys())
|
| 289 |
+
frame_prompts = list(prompt.values())
|
| 290 |
+
frame_negative_indices = list(negative_prompt.keys())
|
| 291 |
+
frame_negative_prompts = list(negative_prompt.values())
|
| 292 |
+
|
| 293 |
+
# Generate and interpolate positive prompts
|
| 294 |
+
prompt_embeds, _ = self.encode_prompt(
|
| 295 |
+
prompt=frame_prompts,
|
| 296 |
+
device=device,
|
| 297 |
+
num_images_per_prompt=num_videos_per_prompt,
|
| 298 |
+
do_classifier_free_guidance=False,
|
| 299 |
+
negative_prompt=None,
|
| 300 |
+
prompt_embeds=None,
|
| 301 |
+
negative_prompt_embeds=None,
|
| 302 |
+
lora_scale=lora_scale,
|
| 303 |
+
clip_skip=clip_skip,
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
shape = (num_frames, *prompt_embeds.shape[1:])
|
| 307 |
+
prompt_interpolation_embeds = prompt_embeds.new_zeros(shape)
|
| 308 |
+
|
| 309 |
+
for i in range(len(frame_indices) - 1):
|
| 310 |
+
start_frame = frame_indices[i]
|
| 311 |
+
end_frame = frame_indices[i + 1]
|
| 312 |
+
start_tensor = prompt_embeds[i].unsqueeze(0)
|
| 313 |
+
end_tensor = prompt_embeds[i + 1].unsqueeze(0)
|
| 314 |
+
|
| 315 |
+
prompt_interpolation_embeds[start_frame : end_frame + 1] = self._free_noise_prompt_interpolation_callback(
|
| 316 |
+
start_frame, end_frame, start_tensor, end_tensor
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
# Generate and interpolate negative prompts
|
| 320 |
+
negative_prompt_embeds = None
|
| 321 |
+
negative_prompt_interpolation_embeds = None
|
| 322 |
+
|
| 323 |
+
if do_classifier_free_guidance:
|
| 324 |
+
_, negative_prompt_embeds = self.encode_prompt(
|
| 325 |
+
prompt=[""] * len(frame_negative_prompts),
|
| 326 |
+
device=device,
|
| 327 |
+
num_images_per_prompt=num_videos_per_prompt,
|
| 328 |
+
do_classifier_free_guidance=True,
|
| 329 |
+
negative_prompt=frame_negative_prompts,
|
| 330 |
+
prompt_embeds=None,
|
| 331 |
+
negative_prompt_embeds=None,
|
| 332 |
+
lora_scale=lora_scale,
|
| 333 |
+
clip_skip=clip_skip,
|
| 334 |
+
)
|
| 335 |
+
|
| 336 |
+
negative_prompt_interpolation_embeds = negative_prompt_embeds.new_zeros(shape)
|
| 337 |
+
|
| 338 |
+
for i in range(len(frame_negative_indices) - 1):
|
| 339 |
+
start_frame = frame_negative_indices[i]
|
| 340 |
+
end_frame = frame_negative_indices[i + 1]
|
| 341 |
+
start_tensor = negative_prompt_embeds[i].unsqueeze(0)
|
| 342 |
+
end_tensor = negative_prompt_embeds[i + 1].unsqueeze(0)
|
| 343 |
+
|
| 344 |
+
negative_prompt_interpolation_embeds[start_frame : end_frame + 1] = (
|
| 345 |
+
self._free_noise_prompt_interpolation_callback(start_frame, end_frame, start_tensor, end_tensor)
|
| 346 |
+
)
|
| 347 |
+
|
| 348 |
+
prompt_embeds = prompt_interpolation_embeds
|
| 349 |
+
negative_prompt_embeds = negative_prompt_interpolation_embeds
|
| 350 |
+
|
| 351 |
+
if do_classifier_free_guidance:
|
| 352 |
+
prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
|
| 353 |
+
|
| 354 |
+
return prompt_embeds, negative_prompt_embeds
|
| 355 |
+
|
| 356 |
+
def _prepare_latents_free_noise(
|
| 357 |
+
self,
|
| 358 |
+
batch_size: int,
|
| 359 |
+
num_channels_latents: int,
|
| 360 |
+
num_frames: int,
|
| 361 |
+
height: int,
|
| 362 |
+
width: int,
|
| 363 |
+
dtype: torch.dtype,
|
| 364 |
+
device: torch.device,
|
| 365 |
+
generator: Optional[torch.Generator] = None,
|
| 366 |
+
latents: Optional[torch.Tensor] = None,
|
| 367 |
+
):
|
| 368 |
+
if isinstance(generator, list) and len(generator) != batch_size:
|
| 369 |
+
raise ValueError(
|
| 370 |
+
f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
|
| 371 |
+
f" size of {batch_size}. Make sure the batch size matches the length of the generators."
|
| 372 |
+
)
|
| 373 |
+
|
| 374 |
+
context_num_frames = (
|
| 375 |
+
self._free_noise_context_length if self._free_noise_context_length == "repeat_context" else num_frames
|
| 376 |
+
)
|
| 377 |
+
|
| 378 |
+
shape = (
|
| 379 |
+
batch_size,
|
| 380 |
+
num_channels_latents,
|
| 381 |
+
context_num_frames,
|
| 382 |
+
height // self.vae_scale_factor,
|
| 383 |
+
width // self.vae_scale_factor,
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
if latents is None:
|
| 387 |
+
latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
|
| 388 |
+
if self._free_noise_noise_type == "random":
|
| 389 |
+
return latents
|
| 390 |
+
else:
|
| 391 |
+
if latents.size(2) == num_frames:
|
| 392 |
+
return latents
|
| 393 |
+
elif latents.size(2) != self._free_noise_context_length:
|
| 394 |
+
raise ValueError(
|
| 395 |
+
f"You have passed `latents` as a parameter to FreeNoise. The expected number of frames is either {num_frames} or {self._free_noise_context_length}, but found {latents.size(2)}"
|
| 396 |
+
)
|
| 397 |
+
latents = latents.to(device)
|
| 398 |
+
|
| 399 |
+
if self._free_noise_noise_type == "shuffle_context":
|
| 400 |
+
for i in range(self._free_noise_context_length, num_frames, self._free_noise_context_stride):
|
| 401 |
+
# ensure window is within bounds
|
| 402 |
+
window_start = max(0, i - self._free_noise_context_length)
|
| 403 |
+
window_end = min(num_frames, window_start + self._free_noise_context_stride)
|
| 404 |
+
window_length = window_end - window_start
|
| 405 |
+
|
| 406 |
+
if window_length == 0:
|
| 407 |
+
break
|
| 408 |
+
|
| 409 |
+
indices = torch.LongTensor(list(range(window_start, window_end)))
|
| 410 |
+
shuffled_indices = indices[torch.randperm(window_length, generator=generator)]
|
| 411 |
+
|
| 412 |
+
current_start = i
|
| 413 |
+
current_end = min(num_frames, current_start + window_length)
|
| 414 |
+
if current_end == current_start + window_length:
|
| 415 |
+
# batch of frames perfectly fits the window
|
| 416 |
+
latents[:, :, current_start:current_end] = latents[:, :, shuffled_indices]
|
| 417 |
+
else:
|
| 418 |
+
# handle the case where the last batch of frames does not fit perfectly with the window
|
| 419 |
+
prefix_length = current_end - current_start
|
| 420 |
+
shuffled_indices = shuffled_indices[:prefix_length]
|
| 421 |
+
latents[:, :, current_start:current_end] = latents[:, :, shuffled_indices]
|
| 422 |
+
|
| 423 |
+
elif self._free_noise_noise_type == "repeat_context":
|
| 424 |
+
num_repeats = (num_frames + self._free_noise_context_length - 1) // self._free_noise_context_length
|
| 425 |
+
latents = torch.cat([latents] * num_repeats, dim=2)
|
| 426 |
+
|
| 427 |
+
latents = latents[:, :, :num_frames]
|
| 428 |
+
return latents
|
| 429 |
+
|
| 430 |
+
def _lerp(
|
| 431 |
+
self, start_index: int, end_index: int, start_tensor: torch.Tensor, end_tensor: torch.Tensor
|
| 432 |
+
) -> torch.Tensor:
|
| 433 |
+
num_indices = end_index - start_index + 1
|
| 434 |
+
interpolated_tensors = []
|
| 435 |
+
|
| 436 |
+
for i in range(num_indices):
|
| 437 |
+
alpha = i / (num_indices - 1)
|
| 438 |
+
interpolated_tensor = (1 - alpha) * start_tensor + alpha * end_tensor
|
| 439 |
+
interpolated_tensors.append(interpolated_tensor)
|
| 440 |
+
|
| 441 |
+
interpolated_tensors = torch.cat(interpolated_tensors)
|
| 442 |
+
return interpolated_tensors
|
| 443 |
+
|
| 444 |
+
def enable_free_noise(
|
| 445 |
+
self,
|
| 446 |
+
context_length: Optional[int] = 16,
|
| 447 |
+
context_stride: int = 4,
|
| 448 |
+
weighting_scheme: str = "pyramid",
|
| 449 |
+
noise_type: str = "shuffle_context",
|
| 450 |
+
prompt_interpolation_callback: Optional[
|
| 451 |
+
Callable[[DiffusionPipeline, int, int, torch.Tensor, torch.Tensor], torch.Tensor]
|
| 452 |
+
] = None,
|
| 453 |
+
) -> None:
|
| 454 |
+
r"""
|
| 455 |
+
Enable long video generation using FreeNoise.
|
| 456 |
+
|
| 457 |
+
Args:
|
| 458 |
+
context_length (`int`, defaults to `16`, *optional*):
|
| 459 |
+
The number of video frames to process at once. It's recommended to set this to the maximum frames the
|
| 460 |
+
Motion Adapter was trained with (usually 16/24/32). If `None`, the default value from the motion
|
| 461 |
+
adapter config is used.
|
| 462 |
+
context_stride (`int`, *optional*):
|
| 463 |
+
Long videos are generated by processing many frames. FreeNoise processes these frames in sliding
|
| 464 |
+
windows of size `context_length`. Context stride allows you to specify how many frames to skip between
|
| 465 |
+
each window. For example, a context length of 16 and context stride of 4 would process 24 frames as:
|
| 466 |
+
[0, 15], [4, 19], [8, 23] (0-based indexing)
|
| 467 |
+
weighting_scheme (`str`, defaults to `pyramid`):
|
| 468 |
+
Weighting scheme for averaging latents after accumulation in FreeNoise blocks. The following weighting
|
| 469 |
+
schemes are supported currently:
|
| 470 |
+
- "flat"
|
| 471 |
+
Performs weighting averaging with a flat weight pattern: [1, 1, 1, 1, 1].
|
| 472 |
+
- "pyramid"
|
| 473 |
+
Performs weighted averaging with a pyramid like weight pattern: [1, 2, 3, 2, 1].
|
| 474 |
+
- "delayed_reverse_sawtooth"
|
| 475 |
+
Performs weighted averaging with low weights for earlier frames and high-to-low weights for
|
| 476 |
+
later frames: [0.01, 0.01, 3, 2, 1].
|
| 477 |
+
noise_type (`str`, defaults to "shuffle_context"):
|
| 478 |
+
Must be one of ["shuffle_context", "repeat_context", "random"].
|
| 479 |
+
- "shuffle_context"
|
| 480 |
+
Shuffles a fixed batch of `context_length` latents to create a final latent of size
|
| 481 |
+
`num_frames`. This is usually the best setting for most generation scenarios. However, there
|
| 482 |
+
might be visible repetition noticeable in the kinds of motion/animation generated.
|
| 483 |
+
- "repeated_context"
|
| 484 |
+
Repeats a fixed batch of `context_length` latents to create a final latent of size
|
| 485 |
+
`num_frames`.
|
| 486 |
+
- "random"
|
| 487 |
+
The final latents are random without any repetition.
|
| 488 |
+
"""
|
| 489 |
+
|
| 490 |
+
allowed_weighting_scheme = ["flat", "pyramid", "delayed_reverse_sawtooth"]
|
| 491 |
+
allowed_noise_type = ["shuffle_context", "repeat_context", "random"]
|
| 492 |
+
|
| 493 |
+
if context_length > self.motion_adapter.config.motion_max_seq_length:
|
| 494 |
+
logger.warning(
|
| 495 |
+
f"You have set {context_length=} which is greater than {self.motion_adapter.config.motion_max_seq_length=}. This can lead to bad generation results."
|
| 496 |
+
)
|
| 497 |
+
if weighting_scheme not in allowed_weighting_scheme:
|
| 498 |
+
raise ValueError(
|
| 499 |
+
f"The parameter `weighting_scheme` must be one of {allowed_weighting_scheme}, but got {weighting_scheme=}"
|
| 500 |
+
)
|
| 501 |
+
if noise_type not in allowed_noise_type:
|
| 502 |
+
raise ValueError(f"The parameter `noise_type` must be one of {allowed_noise_type}, but got {noise_type=}")
|
| 503 |
+
|
| 504 |
+
self._free_noise_context_length = context_length or self.motion_adapter.config.motion_max_seq_length
|
| 505 |
+
self._free_noise_context_stride = context_stride
|
| 506 |
+
self._free_noise_weighting_scheme = weighting_scheme
|
| 507 |
+
self._free_noise_noise_type = noise_type
|
| 508 |
+
self._free_noise_prompt_interpolation_callback = prompt_interpolation_callback or self._lerp
|
| 509 |
+
|
| 510 |
+
if hasattr(self.unet.mid_block, "motion_modules"):
|
| 511 |
+
blocks = [*self.unet.down_blocks, self.unet.mid_block, *self.unet.up_blocks]
|
| 512 |
+
else:
|
| 513 |
+
blocks = [*self.unet.down_blocks, *self.unet.up_blocks]
|
| 514 |
+
|
| 515 |
+
for block in blocks:
|
| 516 |
+
self._enable_free_noise_in_block(block)
|
| 517 |
+
|
| 518 |
+
def disable_free_noise(self) -> None:
|
| 519 |
+
r"""Disable the FreeNoise sampling mechanism."""
|
| 520 |
+
self._free_noise_context_length = None
|
| 521 |
+
|
| 522 |
+
if hasattr(self.unet.mid_block, "motion_modules"):
|
| 523 |
+
blocks = [*self.unet.down_blocks, self.unet.mid_block, *self.unet.up_blocks]
|
| 524 |
+
else:
|
| 525 |
+
blocks = [*self.unet.down_blocks, *self.unet.up_blocks]
|
| 526 |
+
|
| 527 |
+
blocks = [*self.unet.down_blocks, self.unet.mid_block, *self.unet.up_blocks]
|
| 528 |
+
for block in blocks:
|
| 529 |
+
self._disable_free_noise_in_block(block)
|
| 530 |
+
|
| 531 |
+
def _enable_split_inference_motion_modules_(
|
| 532 |
+
self, motion_modules: List[AnimateDiffTransformer3D], spatial_split_size: int
|
| 533 |
+
) -> None:
|
| 534 |
+
for motion_module in motion_modules:
|
| 535 |
+
motion_module.proj_in = SplitInferenceModule(motion_module.proj_in, spatial_split_size, 0, ["input"])
|
| 536 |
+
|
| 537 |
+
for i in range(len(motion_module.transformer_blocks)):
|
| 538 |
+
motion_module.transformer_blocks[i] = SplitInferenceModule(
|
| 539 |
+
motion_module.transformer_blocks[i],
|
| 540 |
+
spatial_split_size,
|
| 541 |
+
0,
|
| 542 |
+
["hidden_states", "encoder_hidden_states"],
|
| 543 |
+
)
|
| 544 |
+
|
| 545 |
+
motion_module.proj_out = SplitInferenceModule(motion_module.proj_out, spatial_split_size, 0, ["input"])
|
| 546 |
+
|
| 547 |
+
def _enable_split_inference_attentions_(
|
| 548 |
+
self, attentions: List[Transformer2DModel], temporal_split_size: int
|
| 549 |
+
) -> None:
|
| 550 |
+
for i in range(len(attentions)):
|
| 551 |
+
attentions[i] = SplitInferenceModule(
|
| 552 |
+
attentions[i], temporal_split_size, 0, ["hidden_states", "encoder_hidden_states"]
|
| 553 |
+
)
|
| 554 |
+
|
| 555 |
+
def _enable_split_inference_resnets_(self, resnets: List[ResnetBlock2D], temporal_split_size: int) -> None:
|
| 556 |
+
for i in range(len(resnets)):
|
| 557 |
+
resnets[i] = SplitInferenceModule(resnets[i], temporal_split_size, 0, ["input_tensor", "temb"])
|
| 558 |
+
|
| 559 |
+
def _enable_split_inference_samplers_(
|
| 560 |
+
self, samplers: Union[List[Downsample2D], List[Upsample2D]], temporal_split_size: int
|
| 561 |
+
) -> None:
|
| 562 |
+
for i in range(len(samplers)):
|
| 563 |
+
samplers[i] = SplitInferenceModule(samplers[i], temporal_split_size, 0, ["hidden_states"])
|
| 564 |
+
|
| 565 |
+
def enable_free_noise_split_inference(self, spatial_split_size: int = 256, temporal_split_size: int = 16) -> None:
|
| 566 |
+
r"""
|
| 567 |
+
Enable FreeNoise memory optimizations by utilizing
|
| 568 |
+
[`~diffusers.pipelines.free_noise_utils.SplitInferenceModule`] across different intermediate modeling blocks.
|
| 569 |
+
|
| 570 |
+
Args:
|
| 571 |
+
spatial_split_size (`int`, defaults to `256`):
|
| 572 |
+
The split size across spatial dimensions for internal blocks. This is used in facilitating split
|
| 573 |
+
inference across the effective batch dimension (`[B x H x W, F, C]`) of intermediate tensors in motion
|
| 574 |
+
modeling blocks.
|
| 575 |
+
temporal_split_size (`int`, defaults to `16`):
|
| 576 |
+
The split size across temporal dimensions for internal blocks. This is used in facilitating split
|
| 577 |
+
inference across the effective batch dimension (`[B x F, H x W, C]`) of intermediate tensors in spatial
|
| 578 |
+
attention, resnets, downsampling and upsampling blocks.
|
| 579 |
+
"""
|
| 580 |
+
# TODO(aryan): Discuss on what's the best way to provide more control to users
|
| 581 |
+
blocks = [*self.unet.down_blocks, self.unet.mid_block, *self.unet.up_blocks]
|
| 582 |
+
for block in blocks:
|
| 583 |
+
if getattr(block, "motion_modules", None) is not None:
|
| 584 |
+
self._enable_split_inference_motion_modules_(block.motion_modules, spatial_split_size)
|
| 585 |
+
if getattr(block, "attentions", None) is not None:
|
| 586 |
+
self._enable_split_inference_attentions_(block.attentions, temporal_split_size)
|
| 587 |
+
if getattr(block, "resnets", None) is not None:
|
| 588 |
+
self._enable_split_inference_resnets_(block.resnets, temporal_split_size)
|
| 589 |
+
if getattr(block, "downsamplers", None) is not None:
|
| 590 |
+
self._enable_split_inference_samplers_(block.downsamplers, temporal_split_size)
|
| 591 |
+
if getattr(block, "upsamplers", None) is not None:
|
| 592 |
+
self._enable_split_inference_samplers_(block.upsamplers, temporal_split_size)
|
| 593 |
+
|
| 594 |
+
@property
|
| 595 |
+
def free_noise_enabled(self):
|
| 596 |
+
return hasattr(self, "_free_noise_context_length") and self._free_noise_context_length is not None
|
venv/lib/python3.10/site-packages/diffusers/pipelines/onnx_utils.py
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
import os
|
| 19 |
+
import shutil
|
| 20 |
+
from pathlib import Path
|
| 21 |
+
from typing import Optional, Union
|
| 22 |
+
|
| 23 |
+
import numpy as np
|
| 24 |
+
from huggingface_hub import hf_hub_download
|
| 25 |
+
from huggingface_hub.utils import validate_hf_hub_args
|
| 26 |
+
|
| 27 |
+
from ..utils import ONNX_EXTERNAL_WEIGHTS_NAME, ONNX_WEIGHTS_NAME, is_onnx_available, logging
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
if is_onnx_available():
|
| 31 |
+
import onnxruntime as ort
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
logger = logging.get_logger(__name__)
|
| 35 |
+
|
| 36 |
+
ORT_TO_NP_TYPE = {
|
| 37 |
+
"tensor(bool)": np.bool_,
|
| 38 |
+
"tensor(int8)": np.int8,
|
| 39 |
+
"tensor(uint8)": np.uint8,
|
| 40 |
+
"tensor(int16)": np.int16,
|
| 41 |
+
"tensor(uint16)": np.uint16,
|
| 42 |
+
"tensor(int32)": np.int32,
|
| 43 |
+
"tensor(uint32)": np.uint32,
|
| 44 |
+
"tensor(int64)": np.int64,
|
| 45 |
+
"tensor(uint64)": np.uint64,
|
| 46 |
+
"tensor(float16)": np.float16,
|
| 47 |
+
"tensor(float)": np.float32,
|
| 48 |
+
"tensor(double)": np.float64,
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class OnnxRuntimeModel:
|
| 53 |
+
def __init__(self, model=None, **kwargs):
|
| 54 |
+
logger.info("`diffusers.OnnxRuntimeModel` is experimental and might change in the future.")
|
| 55 |
+
self.model = model
|
| 56 |
+
self.model_save_dir = kwargs.get("model_save_dir", None)
|
| 57 |
+
self.latest_model_name = kwargs.get("latest_model_name", ONNX_WEIGHTS_NAME)
|
| 58 |
+
|
| 59 |
+
def __call__(self, **kwargs):
|
| 60 |
+
inputs = {k: np.array(v) for k, v in kwargs.items()}
|
| 61 |
+
return self.model.run(None, inputs)
|
| 62 |
+
|
| 63 |
+
@staticmethod
|
| 64 |
+
def load_model(path: Union[str, Path], provider=None, sess_options=None, provider_options=None):
|
| 65 |
+
"""
|
| 66 |
+
Loads an ONNX Inference session with an ExecutionProvider. Default provider is `CPUExecutionProvider`
|
| 67 |
+
|
| 68 |
+
Arguments:
|
| 69 |
+
path (`str` or `Path`):
|
| 70 |
+
Directory from which to load
|
| 71 |
+
provider(`str`, *optional*):
|
| 72 |
+
Onnxruntime execution provider to use for loading the model, defaults to `CPUExecutionProvider`
|
| 73 |
+
"""
|
| 74 |
+
if provider is None:
|
| 75 |
+
logger.info("No onnxruntime provider specified, using CPUExecutionProvider")
|
| 76 |
+
provider = "CPUExecutionProvider"
|
| 77 |
+
|
| 78 |
+
if provider_options is None:
|
| 79 |
+
provider_options = []
|
| 80 |
+
elif not isinstance(provider_options, list):
|
| 81 |
+
provider_options = [provider_options]
|
| 82 |
+
|
| 83 |
+
return ort.InferenceSession(
|
| 84 |
+
path, providers=[provider], sess_options=sess_options, provider_options=provider_options
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
def _save_pretrained(self, save_directory: Union[str, Path], file_name: Optional[str] = None, **kwargs):
|
| 88 |
+
"""
|
| 89 |
+
Save a model and its configuration file to a directory, so that it can be re-loaded using the
|
| 90 |
+
[`~optimum.onnxruntime.modeling_ort.ORTModel.from_pretrained`] class method. It will always save the
|
| 91 |
+
latest_model_name.
|
| 92 |
+
|
| 93 |
+
Arguments:
|
| 94 |
+
save_directory (`str` or `Path`):
|
| 95 |
+
Directory where to save the model file.
|
| 96 |
+
file_name(`str`, *optional*):
|
| 97 |
+
Overwrites the default model file name from `"model.onnx"` to `file_name`. This allows you to save the
|
| 98 |
+
model with a different name.
|
| 99 |
+
"""
|
| 100 |
+
model_file_name = file_name if file_name is not None else ONNX_WEIGHTS_NAME
|
| 101 |
+
|
| 102 |
+
src_path = self.model_save_dir.joinpath(self.latest_model_name)
|
| 103 |
+
dst_path = Path(save_directory).joinpath(model_file_name)
|
| 104 |
+
try:
|
| 105 |
+
shutil.copyfile(src_path, dst_path)
|
| 106 |
+
except shutil.SameFileError:
|
| 107 |
+
pass
|
| 108 |
+
|
| 109 |
+
# copy external weights (for models >2GB)
|
| 110 |
+
src_path = self.model_save_dir.joinpath(ONNX_EXTERNAL_WEIGHTS_NAME)
|
| 111 |
+
if src_path.exists():
|
| 112 |
+
dst_path = Path(save_directory).joinpath(ONNX_EXTERNAL_WEIGHTS_NAME)
|
| 113 |
+
try:
|
| 114 |
+
shutil.copyfile(src_path, dst_path)
|
| 115 |
+
except shutil.SameFileError:
|
| 116 |
+
pass
|
| 117 |
+
|
| 118 |
+
def save_pretrained(
|
| 119 |
+
self,
|
| 120 |
+
save_directory: Union[str, os.PathLike],
|
| 121 |
+
**kwargs,
|
| 122 |
+
):
|
| 123 |
+
"""
|
| 124 |
+
Save a model to a directory, so that it can be re-loaded using the [`~OnnxModel.from_pretrained`] class
|
| 125 |
+
method.:
|
| 126 |
+
|
| 127 |
+
Arguments:
|
| 128 |
+
save_directory (`str` or `os.PathLike`):
|
| 129 |
+
Directory to which to save. Will be created if it doesn't exist.
|
| 130 |
+
"""
|
| 131 |
+
if os.path.isfile(save_directory):
|
| 132 |
+
logger.error(f"Provided path ({save_directory}) should be a directory, not a file")
|
| 133 |
+
return
|
| 134 |
+
|
| 135 |
+
os.makedirs(save_directory, exist_ok=True)
|
| 136 |
+
|
| 137 |
+
# saving model weights/files
|
| 138 |
+
self._save_pretrained(save_directory, **kwargs)
|
| 139 |
+
|
| 140 |
+
@classmethod
|
| 141 |
+
@validate_hf_hub_args
|
| 142 |
+
def _from_pretrained(
|
| 143 |
+
cls,
|
| 144 |
+
model_id: Union[str, Path],
|
| 145 |
+
token: Optional[Union[bool, str, None]] = None,
|
| 146 |
+
revision: Optional[Union[str, None]] = None,
|
| 147 |
+
force_download: bool = False,
|
| 148 |
+
cache_dir: Optional[str] = None,
|
| 149 |
+
file_name: Optional[str] = None,
|
| 150 |
+
provider: Optional[str] = None,
|
| 151 |
+
sess_options: Optional["ort.SessionOptions"] = None,
|
| 152 |
+
**kwargs,
|
| 153 |
+
):
|
| 154 |
+
"""
|
| 155 |
+
Load a model from a directory or the HF Hub.
|
| 156 |
+
|
| 157 |
+
Arguments:
|
| 158 |
+
model_id (`str` or `Path`):
|
| 159 |
+
Directory from which to load
|
| 160 |
+
token (`str` or `bool`):
|
| 161 |
+
Is needed to load models from a private or gated repository
|
| 162 |
+
revision (`str`):
|
| 163 |
+
Revision is the specific model version to use. It can be a branch name, a tag name, or a commit id
|
| 164 |
+
cache_dir (`Union[str, Path]`, *optional*):
|
| 165 |
+
Path to a directory in which a downloaded pretrained model configuration should be cached if the
|
| 166 |
+
standard cache should not be used.
|
| 167 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 168 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 169 |
+
cached versions if they exist.
|
| 170 |
+
file_name(`str`):
|
| 171 |
+
Overwrites the default model file name from `"model.onnx"` to `file_name`. This allows you to load
|
| 172 |
+
different model files from the same repository or directory.
|
| 173 |
+
provider(`str`):
|
| 174 |
+
The ONNX runtime provider, e.g. `CPUExecutionProvider` or `CUDAExecutionProvider`.
|
| 175 |
+
kwargs (`Dict`, *optional*):
|
| 176 |
+
kwargs will be passed to the model during initialization
|
| 177 |
+
"""
|
| 178 |
+
model_file_name = file_name if file_name is not None else ONNX_WEIGHTS_NAME
|
| 179 |
+
# load model from local directory
|
| 180 |
+
if os.path.isdir(model_id):
|
| 181 |
+
model = OnnxRuntimeModel.load_model(
|
| 182 |
+
Path(model_id, model_file_name).as_posix(),
|
| 183 |
+
provider=provider,
|
| 184 |
+
sess_options=sess_options,
|
| 185 |
+
provider_options=kwargs.pop("provider_options"),
|
| 186 |
+
)
|
| 187 |
+
kwargs["model_save_dir"] = Path(model_id)
|
| 188 |
+
# load model from hub
|
| 189 |
+
else:
|
| 190 |
+
# download model
|
| 191 |
+
model_cache_path = hf_hub_download(
|
| 192 |
+
repo_id=model_id,
|
| 193 |
+
filename=model_file_name,
|
| 194 |
+
token=token,
|
| 195 |
+
revision=revision,
|
| 196 |
+
cache_dir=cache_dir,
|
| 197 |
+
force_download=force_download,
|
| 198 |
+
)
|
| 199 |
+
kwargs["model_save_dir"] = Path(model_cache_path).parent
|
| 200 |
+
kwargs["latest_model_name"] = Path(model_cache_path).name
|
| 201 |
+
model = OnnxRuntimeModel.load_model(
|
| 202 |
+
model_cache_path,
|
| 203 |
+
provider=provider,
|
| 204 |
+
sess_options=sess_options,
|
| 205 |
+
provider_options=kwargs.pop("provider_options"),
|
| 206 |
+
)
|
| 207 |
+
return cls(model=model, **kwargs)
|
| 208 |
+
|
| 209 |
+
@classmethod
|
| 210 |
+
@validate_hf_hub_args
|
| 211 |
+
def from_pretrained(
|
| 212 |
+
cls,
|
| 213 |
+
model_id: Union[str, Path],
|
| 214 |
+
force_download: bool = True,
|
| 215 |
+
token: Optional[str] = None,
|
| 216 |
+
cache_dir: Optional[str] = None,
|
| 217 |
+
**model_kwargs,
|
| 218 |
+
):
|
| 219 |
+
revision = None
|
| 220 |
+
if len(str(model_id).split("@")) == 2:
|
| 221 |
+
model_id, revision = model_id.split("@")
|
| 222 |
+
|
| 223 |
+
return cls._from_pretrained(
|
| 224 |
+
model_id=model_id,
|
| 225 |
+
revision=revision,
|
| 226 |
+
cache_dir=cache_dir,
|
| 227 |
+
force_download=force_download,
|
| 228 |
+
token=token,
|
| 229 |
+
**model_kwargs,
|
| 230 |
+
)
|
venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_flax_utils.py
ADDED
|
@@ -0,0 +1,610 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
| 4 |
+
#
|
| 5 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 6 |
+
# you may not use this file except in compliance with the License.
|
| 7 |
+
# You may obtain a copy of the License at
|
| 8 |
+
#
|
| 9 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 10 |
+
#
|
| 11 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 12 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 13 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 14 |
+
# See the License for the specific language governing permissions and
|
| 15 |
+
# limitations under the License.
|
| 16 |
+
|
| 17 |
+
import importlib
|
| 18 |
+
import inspect
|
| 19 |
+
import os
|
| 20 |
+
from typing import Any, Dict, List, Optional, Union
|
| 21 |
+
|
| 22 |
+
import flax
|
| 23 |
+
import numpy as np
|
| 24 |
+
import PIL.Image
|
| 25 |
+
from flax.core.frozen_dict import FrozenDict
|
| 26 |
+
from huggingface_hub import create_repo, snapshot_download
|
| 27 |
+
from huggingface_hub.utils import validate_hf_hub_args
|
| 28 |
+
from PIL import Image
|
| 29 |
+
from tqdm.auto import tqdm
|
| 30 |
+
|
| 31 |
+
from ..configuration_utils import ConfigMixin
|
| 32 |
+
from ..models.modeling_flax_utils import FLAX_WEIGHTS_NAME, FlaxModelMixin
|
| 33 |
+
from ..schedulers.scheduling_utils_flax import SCHEDULER_CONFIG_NAME, FlaxSchedulerMixin
|
| 34 |
+
from ..utils import (
|
| 35 |
+
CONFIG_NAME,
|
| 36 |
+
BaseOutput,
|
| 37 |
+
PushToHubMixin,
|
| 38 |
+
http_user_agent,
|
| 39 |
+
is_transformers_available,
|
| 40 |
+
logging,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
if is_transformers_available():
|
| 45 |
+
from transformers import FlaxPreTrainedModel
|
| 46 |
+
|
| 47 |
+
INDEX_FILE = "diffusion_flax_model.bin"
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
logger = logging.get_logger(__name__)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
LOADABLE_CLASSES = {
|
| 54 |
+
"diffusers": {
|
| 55 |
+
"FlaxModelMixin": ["save_pretrained", "from_pretrained"],
|
| 56 |
+
"FlaxSchedulerMixin": ["save_pretrained", "from_pretrained"],
|
| 57 |
+
"FlaxDiffusionPipeline": ["save_pretrained", "from_pretrained"],
|
| 58 |
+
},
|
| 59 |
+
"transformers": {
|
| 60 |
+
"PreTrainedTokenizer": ["save_pretrained", "from_pretrained"],
|
| 61 |
+
"PreTrainedTokenizerFast": ["save_pretrained", "from_pretrained"],
|
| 62 |
+
"FlaxPreTrainedModel": ["save_pretrained", "from_pretrained"],
|
| 63 |
+
"FeatureExtractionMixin": ["save_pretrained", "from_pretrained"],
|
| 64 |
+
"ProcessorMixin": ["save_pretrained", "from_pretrained"],
|
| 65 |
+
"ImageProcessingMixin": ["save_pretrained", "from_pretrained"],
|
| 66 |
+
},
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
ALL_IMPORTABLE_CLASSES = {}
|
| 70 |
+
for library in LOADABLE_CLASSES:
|
| 71 |
+
ALL_IMPORTABLE_CLASSES.update(LOADABLE_CLASSES[library])
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def import_flax_or_no_model(module, class_name):
|
| 75 |
+
try:
|
| 76 |
+
# 1. First make sure that if a Flax object is present, import this one
|
| 77 |
+
class_obj = getattr(module, "Flax" + class_name)
|
| 78 |
+
except AttributeError:
|
| 79 |
+
# 2. If this doesn't work, it's not a model and we don't append "Flax"
|
| 80 |
+
class_obj = getattr(module, class_name)
|
| 81 |
+
except AttributeError:
|
| 82 |
+
raise ValueError(f"Neither Flax{class_name} nor {class_name} exist in {module}")
|
| 83 |
+
|
| 84 |
+
return class_obj
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
@flax.struct.dataclass
|
| 88 |
+
class FlaxImagePipelineOutput(BaseOutput):
|
| 89 |
+
"""
|
| 90 |
+
Output class for image pipelines.
|
| 91 |
+
|
| 92 |
+
Args:
|
| 93 |
+
images (`List[PIL.Image.Image]` or `np.ndarray`)
|
| 94 |
+
List of denoised PIL images of length `batch_size` or NumPy array of shape `(batch_size, height, width,
|
| 95 |
+
num_channels)`.
|
| 96 |
+
"""
|
| 97 |
+
|
| 98 |
+
images: Union[List[PIL.Image.Image], np.ndarray]
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
class FlaxDiffusionPipeline(ConfigMixin, PushToHubMixin):
|
| 102 |
+
r"""
|
| 103 |
+
Base class for Flax-based pipelines.
|
| 104 |
+
|
| 105 |
+
[`FlaxDiffusionPipeline`] stores all components (models, schedulers, and processors) for diffusion pipelines and
|
| 106 |
+
provides methods for loading, downloading and saving models. It also includes methods to:
|
| 107 |
+
|
| 108 |
+
- enable/disable the progress bar for the denoising iteration
|
| 109 |
+
|
| 110 |
+
Class attributes:
|
| 111 |
+
|
| 112 |
+
- **config_name** ([`str`]) -- The configuration filename that stores the class and module names of all the
|
| 113 |
+
diffusion pipeline's components.
|
| 114 |
+
"""
|
| 115 |
+
|
| 116 |
+
config_name = "model_index.json"
|
| 117 |
+
|
| 118 |
+
def register_modules(self, **kwargs):
|
| 119 |
+
# import it here to avoid circular import
|
| 120 |
+
from diffusers import pipelines
|
| 121 |
+
|
| 122 |
+
for name, module in kwargs.items():
|
| 123 |
+
if module is None:
|
| 124 |
+
register_dict = {name: (None, None)}
|
| 125 |
+
else:
|
| 126 |
+
# retrieve library
|
| 127 |
+
library = module.__module__.split(".")[0]
|
| 128 |
+
|
| 129 |
+
# check if the module is a pipeline module
|
| 130 |
+
pipeline_dir = module.__module__.split(".")[-2]
|
| 131 |
+
path = module.__module__.split(".")
|
| 132 |
+
is_pipeline_module = pipeline_dir in path and hasattr(pipelines, pipeline_dir)
|
| 133 |
+
|
| 134 |
+
# if library is not in LOADABLE_CLASSES, then it is a custom module.
|
| 135 |
+
# Or if it's a pipeline module, then the module is inside the pipeline
|
| 136 |
+
# folder so we set the library to module name.
|
| 137 |
+
if library not in LOADABLE_CLASSES or is_pipeline_module:
|
| 138 |
+
library = pipeline_dir
|
| 139 |
+
|
| 140 |
+
# retrieve class_name
|
| 141 |
+
class_name = module.__class__.__name__
|
| 142 |
+
|
| 143 |
+
register_dict = {name: (library, class_name)}
|
| 144 |
+
|
| 145 |
+
# save model index config
|
| 146 |
+
self.register_to_config(**register_dict)
|
| 147 |
+
|
| 148 |
+
# set models
|
| 149 |
+
setattr(self, name, module)
|
| 150 |
+
|
| 151 |
+
def save_pretrained(
|
| 152 |
+
self,
|
| 153 |
+
save_directory: Union[str, os.PathLike],
|
| 154 |
+
params: Union[Dict, FrozenDict],
|
| 155 |
+
push_to_hub: bool = False,
|
| 156 |
+
**kwargs,
|
| 157 |
+
):
|
| 158 |
+
# TODO: handle inference_state
|
| 159 |
+
"""
|
| 160 |
+
Save all saveable variables of the pipeline to a directory. A pipeline variable can be saved and loaded if its
|
| 161 |
+
class implements both a save and loading method. The pipeline is easily reloaded using the
|
| 162 |
+
[`~FlaxDiffusionPipeline.from_pretrained`] class method.
|
| 163 |
+
|
| 164 |
+
Arguments:
|
| 165 |
+
save_directory (`str` or `os.PathLike`):
|
| 166 |
+
Directory to which to save. Will be created if it doesn't exist.
|
| 167 |
+
push_to_hub (`bool`, *optional*, defaults to `False`):
|
| 168 |
+
Whether or not to push your model to the Hugging Face model hub after saving it. You can specify the
|
| 169 |
+
repository you want to push to with `repo_id` (will default to the name of `save_directory` in your
|
| 170 |
+
namespace).
|
| 171 |
+
kwargs (`Dict[str, Any]`, *optional*):
|
| 172 |
+
Additional keyword arguments passed along to the [`~utils.PushToHubMixin.push_to_hub`] method.
|
| 173 |
+
"""
|
| 174 |
+
self.save_config(save_directory)
|
| 175 |
+
|
| 176 |
+
model_index_dict = dict(self.config)
|
| 177 |
+
model_index_dict.pop("_class_name")
|
| 178 |
+
model_index_dict.pop("_diffusers_version")
|
| 179 |
+
model_index_dict.pop("_module", None)
|
| 180 |
+
|
| 181 |
+
if push_to_hub:
|
| 182 |
+
commit_message = kwargs.pop("commit_message", None)
|
| 183 |
+
private = kwargs.pop("private", None)
|
| 184 |
+
create_pr = kwargs.pop("create_pr", False)
|
| 185 |
+
token = kwargs.pop("token", None)
|
| 186 |
+
repo_id = kwargs.pop("repo_id", save_directory.split(os.path.sep)[-1])
|
| 187 |
+
repo_id = create_repo(repo_id, exist_ok=True, private=private, token=token).repo_id
|
| 188 |
+
|
| 189 |
+
for pipeline_component_name in model_index_dict.keys():
|
| 190 |
+
sub_model = getattr(self, pipeline_component_name)
|
| 191 |
+
if sub_model is None:
|
| 192 |
+
# edge case for saving a pipeline with safety_checker=None
|
| 193 |
+
continue
|
| 194 |
+
|
| 195 |
+
model_cls = sub_model.__class__
|
| 196 |
+
|
| 197 |
+
save_method_name = None
|
| 198 |
+
# search for the model's base class in LOADABLE_CLASSES
|
| 199 |
+
for library_name, library_classes in LOADABLE_CLASSES.items():
|
| 200 |
+
library = importlib.import_module(library_name)
|
| 201 |
+
for base_class, save_load_methods in library_classes.items():
|
| 202 |
+
class_candidate = getattr(library, base_class, None)
|
| 203 |
+
if class_candidate is not None and issubclass(model_cls, class_candidate):
|
| 204 |
+
# if we found a suitable base class in LOADABLE_CLASSES then grab its save method
|
| 205 |
+
save_method_name = save_load_methods[0]
|
| 206 |
+
break
|
| 207 |
+
if save_method_name is not None:
|
| 208 |
+
break
|
| 209 |
+
|
| 210 |
+
save_method = getattr(sub_model, save_method_name)
|
| 211 |
+
expects_params = "params" in set(inspect.signature(save_method).parameters.keys())
|
| 212 |
+
|
| 213 |
+
if expects_params:
|
| 214 |
+
save_method(
|
| 215 |
+
os.path.join(save_directory, pipeline_component_name), params=params[pipeline_component_name]
|
| 216 |
+
)
|
| 217 |
+
else:
|
| 218 |
+
save_method(os.path.join(save_directory, pipeline_component_name))
|
| 219 |
+
|
| 220 |
+
if push_to_hub:
|
| 221 |
+
self._upload_folder(
|
| 222 |
+
save_directory,
|
| 223 |
+
repo_id,
|
| 224 |
+
token=token,
|
| 225 |
+
commit_message=commit_message,
|
| 226 |
+
create_pr=create_pr,
|
| 227 |
+
)
|
| 228 |
+
|
| 229 |
+
@classmethod
|
| 230 |
+
@validate_hf_hub_args
|
| 231 |
+
def from_pretrained(cls, pretrained_model_name_or_path: Optional[Union[str, os.PathLike]], **kwargs):
|
| 232 |
+
r"""
|
| 233 |
+
Instantiate a Flax-based diffusion pipeline from pretrained pipeline weights.
|
| 234 |
+
|
| 235 |
+
The pipeline is set in evaluation mode (`model.eval()) by default and dropout modules are deactivated.
|
| 236 |
+
|
| 237 |
+
If you get the error message below, you need to finetune the weights for your downstream task:
|
| 238 |
+
|
| 239 |
+
```
|
| 240 |
+
Some weights of FlaxUNet2DConditionModel were not initialized from the model checkpoint at stable-diffusion-v1-5/stable-diffusion-v1-5 and are newly initialized because the shapes did not match:
|
| 241 |
+
```
|
| 242 |
+
|
| 243 |
+
Parameters:
|
| 244 |
+
pretrained_model_name_or_path (`str` or `os.PathLike`, *optional*):
|
| 245 |
+
Can be either:
|
| 246 |
+
|
| 247 |
+
- A string, the *repo id* (for example `stable-diffusion-v1-5/stable-diffusion-v1-5`) of a
|
| 248 |
+
pretrained pipeline hosted on the Hub.
|
| 249 |
+
- A path to a *directory* (for example `./my_model_directory`) containing the model weights saved
|
| 250 |
+
using [`~FlaxDiffusionPipeline.save_pretrained`].
|
| 251 |
+
dtype (`jnp.dtype`, *optional*):
|
| 252 |
+
Override the default `jnp.dtype` and load the model under this dtype.
|
| 253 |
+
force_download (`bool`, *optional*, defaults to `False`):
|
| 254 |
+
Whether or not to force the (re-)download of the model weights and configuration files, overriding the
|
| 255 |
+
cached versions if they exist.
|
| 256 |
+
|
| 257 |
+
proxies (`Dict[str, str]`, *optional*):
|
| 258 |
+
A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
|
| 259 |
+
'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
|
| 260 |
+
output_loading_info(`bool`, *optional*, defaults to `False`):
|
| 261 |
+
Whether or not to also return a dictionary containing missing keys, unexpected keys and error messages.
|
| 262 |
+
local_files_only (`bool`, *optional*, defaults to `False`):
|
| 263 |
+
Whether to only load local model weights and configuration files or not. If set to `True`, the model
|
| 264 |
+
won't be downloaded from the Hub.
|
| 265 |
+
token (`str` or *bool*, *optional*):
|
| 266 |
+
The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
|
| 267 |
+
`diffusers-cli login` (stored in `~/.huggingface`) is used.
|
| 268 |
+
revision (`str`, *optional*, defaults to `"main"`):
|
| 269 |
+
The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
|
| 270 |
+
allowed by Git.
|
| 271 |
+
mirror (`str`, *optional*):
|
| 272 |
+
Mirror source to resolve accessibility issues if you're downloading a model in China. We do not
|
| 273 |
+
guarantee the timeliness or safety of the source, and you should refer to the mirror site for more
|
| 274 |
+
information.
|
| 275 |
+
kwargs (remaining dictionary of keyword arguments, *optional*):
|
| 276 |
+
Can be used to overwrite load and saveable variables (the pipeline components) of the specific pipeline
|
| 277 |
+
class. The overwritten components are passed directly to the pipelines `__init__` method.
|
| 278 |
+
|
| 279 |
+
<Tip>
|
| 280 |
+
|
| 281 |
+
To use private or [gated models](https://huggingface.co/docs/hub/models-gated#gated-models), log-in with
|
| 282 |
+
`huggingface-cli login`.
|
| 283 |
+
|
| 284 |
+
</Tip>
|
| 285 |
+
|
| 286 |
+
Examples:
|
| 287 |
+
|
| 288 |
+
```py
|
| 289 |
+
>>> from diffusers import FlaxDiffusionPipeline
|
| 290 |
+
|
| 291 |
+
>>> # Download pipeline from huggingface.co and cache.
|
| 292 |
+
>>> # Requires to be logged in to Hugging Face hub,
|
| 293 |
+
>>> # see more in [the documentation](https://huggingface.co/docs/hub/security-tokens)
|
| 294 |
+
>>> pipeline, params = FlaxDiffusionPipeline.from_pretrained(
|
| 295 |
+
... "stable-diffusion-v1-5/stable-diffusion-v1-5",
|
| 296 |
+
... variant="bf16",
|
| 297 |
+
... dtype=jnp.bfloat16,
|
| 298 |
+
... )
|
| 299 |
+
|
| 300 |
+
>>> # Download pipeline, but use a different scheduler
|
| 301 |
+
>>> from diffusers import FlaxDPMSolverMultistepScheduler
|
| 302 |
+
|
| 303 |
+
>>> model_id = "stable-diffusion-v1-5/stable-diffusion-v1-5"
|
| 304 |
+
>>> dpmpp, dpmpp_state = FlaxDPMSolverMultistepScheduler.from_pretrained(
|
| 305 |
+
... model_id,
|
| 306 |
+
... subfolder="scheduler",
|
| 307 |
+
... )
|
| 308 |
+
|
| 309 |
+
>>> dpm_pipe, dpm_params = FlaxStableDiffusionPipeline.from_pretrained(
|
| 310 |
+
... model_id, variant="bf16", dtype=jnp.bfloat16, scheduler=dpmpp
|
| 311 |
+
... )
|
| 312 |
+
>>> dpm_params["scheduler"] = dpmpp_state
|
| 313 |
+
```
|
| 314 |
+
"""
|
| 315 |
+
cache_dir = kwargs.pop("cache_dir", None)
|
| 316 |
+
proxies = kwargs.pop("proxies", None)
|
| 317 |
+
local_files_only = kwargs.pop("local_files_only", False)
|
| 318 |
+
token = kwargs.pop("token", None)
|
| 319 |
+
revision = kwargs.pop("revision", None)
|
| 320 |
+
from_pt = kwargs.pop("from_pt", False)
|
| 321 |
+
use_memory_efficient_attention = kwargs.pop("use_memory_efficient_attention", False)
|
| 322 |
+
split_head_dim = kwargs.pop("split_head_dim", False)
|
| 323 |
+
dtype = kwargs.pop("dtype", None)
|
| 324 |
+
|
| 325 |
+
# 1. Download the checkpoints and configs
|
| 326 |
+
# use snapshot download here to get it working from from_pretrained
|
| 327 |
+
if not os.path.isdir(pretrained_model_name_or_path):
|
| 328 |
+
config_dict = cls.load_config(
|
| 329 |
+
pretrained_model_name_or_path,
|
| 330 |
+
cache_dir=cache_dir,
|
| 331 |
+
proxies=proxies,
|
| 332 |
+
local_files_only=local_files_only,
|
| 333 |
+
token=token,
|
| 334 |
+
revision=revision,
|
| 335 |
+
)
|
| 336 |
+
# make sure we only download sub-folders and `diffusers` filenames
|
| 337 |
+
folder_names = [k for k in config_dict.keys() if not k.startswith("_")]
|
| 338 |
+
allow_patterns = [os.path.join(k, "*") for k in folder_names]
|
| 339 |
+
allow_patterns += [FLAX_WEIGHTS_NAME, SCHEDULER_CONFIG_NAME, CONFIG_NAME, cls.config_name]
|
| 340 |
+
|
| 341 |
+
ignore_patterns = ["*.bin", "*.safetensors"] if not from_pt else []
|
| 342 |
+
ignore_patterns += ["*.onnx", "*.onnx_data", "*.xml", "*.pb"]
|
| 343 |
+
|
| 344 |
+
if cls != FlaxDiffusionPipeline:
|
| 345 |
+
requested_pipeline_class = cls.__name__
|
| 346 |
+
else:
|
| 347 |
+
requested_pipeline_class = config_dict.get("_class_name", cls.__name__)
|
| 348 |
+
requested_pipeline_class = (
|
| 349 |
+
requested_pipeline_class
|
| 350 |
+
if requested_pipeline_class.startswith("Flax")
|
| 351 |
+
else "Flax" + requested_pipeline_class
|
| 352 |
+
)
|
| 353 |
+
|
| 354 |
+
user_agent = {"pipeline_class": requested_pipeline_class}
|
| 355 |
+
user_agent = http_user_agent(user_agent)
|
| 356 |
+
|
| 357 |
+
# download all allow_patterns
|
| 358 |
+
cached_folder = snapshot_download(
|
| 359 |
+
pretrained_model_name_or_path,
|
| 360 |
+
cache_dir=cache_dir,
|
| 361 |
+
proxies=proxies,
|
| 362 |
+
local_files_only=local_files_only,
|
| 363 |
+
token=token,
|
| 364 |
+
revision=revision,
|
| 365 |
+
allow_patterns=allow_patterns,
|
| 366 |
+
ignore_patterns=ignore_patterns,
|
| 367 |
+
user_agent=user_agent,
|
| 368 |
+
)
|
| 369 |
+
else:
|
| 370 |
+
cached_folder = pretrained_model_name_or_path
|
| 371 |
+
|
| 372 |
+
config_dict = cls.load_config(cached_folder)
|
| 373 |
+
|
| 374 |
+
# 2. Load the pipeline class, if using custom module then load it from the hub
|
| 375 |
+
# if we load from explicit class, let's use it
|
| 376 |
+
if cls != FlaxDiffusionPipeline:
|
| 377 |
+
pipeline_class = cls
|
| 378 |
+
else:
|
| 379 |
+
diffusers_module = importlib.import_module(cls.__module__.split(".")[0])
|
| 380 |
+
class_name = (
|
| 381 |
+
config_dict["_class_name"]
|
| 382 |
+
if config_dict["_class_name"].startswith("Flax")
|
| 383 |
+
else "Flax" + config_dict["_class_name"]
|
| 384 |
+
)
|
| 385 |
+
pipeline_class = getattr(diffusers_module, class_name)
|
| 386 |
+
|
| 387 |
+
# some modules can be passed directly to the init
|
| 388 |
+
# in this case they are already instantiated in `kwargs`
|
| 389 |
+
# extract them here
|
| 390 |
+
expected_modules, optional_kwargs = cls._get_signature_keys(pipeline_class)
|
| 391 |
+
passed_class_obj = {k: kwargs.pop(k) for k in expected_modules if k in kwargs}
|
| 392 |
+
passed_pipe_kwargs = {k: kwargs.pop(k) for k in optional_kwargs if k in kwargs}
|
| 393 |
+
|
| 394 |
+
init_dict, unused_kwargs, _ = pipeline_class.extract_init_dict(config_dict, **kwargs)
|
| 395 |
+
|
| 396 |
+
# define init kwargs
|
| 397 |
+
init_kwargs = {k: init_dict.pop(k) for k in optional_kwargs if k in init_dict}
|
| 398 |
+
init_kwargs = {**init_kwargs, **passed_pipe_kwargs}
|
| 399 |
+
|
| 400 |
+
# remove `null` components
|
| 401 |
+
def load_module(name, value):
|
| 402 |
+
if value[0] is None:
|
| 403 |
+
return False
|
| 404 |
+
if name in passed_class_obj and passed_class_obj[name] is None:
|
| 405 |
+
return False
|
| 406 |
+
return True
|
| 407 |
+
|
| 408 |
+
init_dict = {k: v for k, v in init_dict.items() if load_module(k, v)}
|
| 409 |
+
|
| 410 |
+
# Throw nice warnings / errors for fast accelerate loading
|
| 411 |
+
if len(unused_kwargs) > 0:
|
| 412 |
+
logger.warning(
|
| 413 |
+
f"Keyword arguments {unused_kwargs} are not expected by {pipeline_class.__name__} and will be ignored."
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
# inference_params
|
| 417 |
+
params = {}
|
| 418 |
+
|
| 419 |
+
# import it here to avoid circular import
|
| 420 |
+
from diffusers import pipelines
|
| 421 |
+
|
| 422 |
+
# 3. Load each module in the pipeline
|
| 423 |
+
for name, (library_name, class_name) in init_dict.items():
|
| 424 |
+
if class_name is None:
|
| 425 |
+
# edge case for when the pipeline was saved with safety_checker=None
|
| 426 |
+
init_kwargs[name] = None
|
| 427 |
+
continue
|
| 428 |
+
|
| 429 |
+
is_pipeline_module = hasattr(pipelines, library_name)
|
| 430 |
+
loaded_sub_model = None
|
| 431 |
+
sub_model_should_be_defined = True
|
| 432 |
+
|
| 433 |
+
# if the model is in a pipeline module, then we load it from the pipeline
|
| 434 |
+
if name in passed_class_obj:
|
| 435 |
+
# 1. check that passed_class_obj has correct parent class
|
| 436 |
+
if not is_pipeline_module:
|
| 437 |
+
library = importlib.import_module(library_name)
|
| 438 |
+
class_obj = getattr(library, class_name)
|
| 439 |
+
importable_classes = LOADABLE_CLASSES[library_name]
|
| 440 |
+
class_candidates = {c: getattr(library, c, None) for c in importable_classes.keys()}
|
| 441 |
+
|
| 442 |
+
expected_class_obj = None
|
| 443 |
+
for class_name, class_candidate in class_candidates.items():
|
| 444 |
+
if class_candidate is not None and issubclass(class_obj, class_candidate):
|
| 445 |
+
expected_class_obj = class_candidate
|
| 446 |
+
|
| 447 |
+
if not issubclass(passed_class_obj[name].__class__, expected_class_obj):
|
| 448 |
+
raise ValueError(
|
| 449 |
+
f"{passed_class_obj[name]} is of type: {type(passed_class_obj[name])}, but should be"
|
| 450 |
+
f" {expected_class_obj}"
|
| 451 |
+
)
|
| 452 |
+
elif passed_class_obj[name] is None:
|
| 453 |
+
logger.warning(
|
| 454 |
+
f"You have passed `None` for {name} to disable its functionality in {pipeline_class}. Note"
|
| 455 |
+
f" that this might lead to problems when using {pipeline_class} and is not recommended."
|
| 456 |
+
)
|
| 457 |
+
sub_model_should_be_defined = False
|
| 458 |
+
else:
|
| 459 |
+
logger.warning(
|
| 460 |
+
f"You have passed a non-standard module {passed_class_obj[name]}. We cannot verify whether it"
|
| 461 |
+
" has the correct type"
|
| 462 |
+
)
|
| 463 |
+
|
| 464 |
+
# set passed class object
|
| 465 |
+
loaded_sub_model = passed_class_obj[name]
|
| 466 |
+
elif is_pipeline_module:
|
| 467 |
+
pipeline_module = getattr(pipelines, library_name)
|
| 468 |
+
class_obj = import_flax_or_no_model(pipeline_module, class_name)
|
| 469 |
+
|
| 470 |
+
importable_classes = ALL_IMPORTABLE_CLASSES
|
| 471 |
+
class_candidates = dict.fromkeys(importable_classes.keys(), class_obj)
|
| 472 |
+
else:
|
| 473 |
+
# else we just import it from the library.
|
| 474 |
+
library = importlib.import_module(library_name)
|
| 475 |
+
class_obj = import_flax_or_no_model(library, class_name)
|
| 476 |
+
|
| 477 |
+
importable_classes = LOADABLE_CLASSES[library_name]
|
| 478 |
+
class_candidates = {c: getattr(library, c, None) for c in importable_classes.keys()}
|
| 479 |
+
|
| 480 |
+
if loaded_sub_model is None and sub_model_should_be_defined:
|
| 481 |
+
load_method_name = None
|
| 482 |
+
for class_name, class_candidate in class_candidates.items():
|
| 483 |
+
if class_candidate is not None and issubclass(class_obj, class_candidate):
|
| 484 |
+
load_method_name = importable_classes[class_name][1]
|
| 485 |
+
|
| 486 |
+
load_method = getattr(class_obj, load_method_name)
|
| 487 |
+
|
| 488 |
+
# check if the module is in a subdirectory
|
| 489 |
+
if os.path.isdir(os.path.join(cached_folder, name)):
|
| 490 |
+
loadable_folder = os.path.join(cached_folder, name)
|
| 491 |
+
else:
|
| 492 |
+
loaded_sub_model = cached_folder
|
| 493 |
+
|
| 494 |
+
if issubclass(class_obj, FlaxModelMixin):
|
| 495 |
+
loaded_sub_model, loaded_params = load_method(
|
| 496 |
+
loadable_folder,
|
| 497 |
+
from_pt=from_pt,
|
| 498 |
+
use_memory_efficient_attention=use_memory_efficient_attention,
|
| 499 |
+
split_head_dim=split_head_dim,
|
| 500 |
+
dtype=dtype,
|
| 501 |
+
)
|
| 502 |
+
params[name] = loaded_params
|
| 503 |
+
elif is_transformers_available() and issubclass(class_obj, FlaxPreTrainedModel):
|
| 504 |
+
if from_pt:
|
| 505 |
+
# TODO(Suraj): Fix this in Transformers. We should be able to use `_do_init=False` here
|
| 506 |
+
loaded_sub_model = load_method(loadable_folder, from_pt=from_pt)
|
| 507 |
+
loaded_params = loaded_sub_model.params
|
| 508 |
+
del loaded_sub_model._params
|
| 509 |
+
else:
|
| 510 |
+
loaded_sub_model, loaded_params = load_method(loadable_folder, _do_init=False)
|
| 511 |
+
params[name] = loaded_params
|
| 512 |
+
elif issubclass(class_obj, FlaxSchedulerMixin):
|
| 513 |
+
loaded_sub_model, scheduler_state = load_method(loadable_folder)
|
| 514 |
+
params[name] = scheduler_state
|
| 515 |
+
else:
|
| 516 |
+
loaded_sub_model = load_method(loadable_folder)
|
| 517 |
+
|
| 518 |
+
init_kwargs[name] = loaded_sub_model # UNet(...), # DiffusionSchedule(...)
|
| 519 |
+
|
| 520 |
+
# 4. Potentially add passed objects if expected
|
| 521 |
+
missing_modules = set(expected_modules) - set(init_kwargs.keys())
|
| 522 |
+
passed_modules = list(passed_class_obj.keys())
|
| 523 |
+
|
| 524 |
+
if len(missing_modules) > 0 and missing_modules <= set(passed_modules):
|
| 525 |
+
for module in missing_modules:
|
| 526 |
+
init_kwargs[module] = passed_class_obj.get(module, None)
|
| 527 |
+
elif len(missing_modules) > 0:
|
| 528 |
+
passed_modules = set(list(init_kwargs.keys()) + list(passed_class_obj.keys())) - optional_kwargs
|
| 529 |
+
raise ValueError(
|
| 530 |
+
f"Pipeline {pipeline_class} expected {expected_modules}, but only {passed_modules} were passed."
|
| 531 |
+
)
|
| 532 |
+
|
| 533 |
+
model = pipeline_class(**init_kwargs, dtype=dtype)
|
| 534 |
+
return model, params
|
| 535 |
+
|
| 536 |
+
@classmethod
|
| 537 |
+
def _get_signature_keys(cls, obj):
|
| 538 |
+
parameters = inspect.signature(obj.__init__).parameters
|
| 539 |
+
required_parameters = {k: v for k, v in parameters.items() if v.default == inspect._empty}
|
| 540 |
+
optional_parameters = set({k for k, v in parameters.items() if v.default != inspect._empty})
|
| 541 |
+
expected_modules = set(required_parameters.keys()) - {"self"}
|
| 542 |
+
|
| 543 |
+
return expected_modules, optional_parameters
|
| 544 |
+
|
| 545 |
+
@property
|
| 546 |
+
def components(self) -> Dict[str, Any]:
|
| 547 |
+
r"""
|
| 548 |
+
|
| 549 |
+
The `self.components` property can be useful to run different pipelines with the same weights and
|
| 550 |
+
configurations to not have to re-allocate memory.
|
| 551 |
+
|
| 552 |
+
Examples:
|
| 553 |
+
|
| 554 |
+
```py
|
| 555 |
+
>>> from diffusers import (
|
| 556 |
+
... FlaxStableDiffusionPipeline,
|
| 557 |
+
... FlaxStableDiffusionImg2ImgPipeline,
|
| 558 |
+
... )
|
| 559 |
+
|
| 560 |
+
>>> text2img = FlaxStableDiffusionPipeline.from_pretrained(
|
| 561 |
+
... "stable-diffusion-v1-5/stable-diffusion-v1-5", variant="bf16", dtype=jnp.bfloat16
|
| 562 |
+
... )
|
| 563 |
+
>>> img2img = FlaxStableDiffusionImg2ImgPipeline(**text2img.components)
|
| 564 |
+
```
|
| 565 |
+
|
| 566 |
+
Returns:
|
| 567 |
+
A dictionary containing all the modules needed to initialize the pipeline.
|
| 568 |
+
"""
|
| 569 |
+
expected_modules, optional_parameters = self._get_signature_keys(self)
|
| 570 |
+
components = {
|
| 571 |
+
k: getattr(self, k) for k in self.config.keys() if not k.startswith("_") and k not in optional_parameters
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
if set(components.keys()) != expected_modules:
|
| 575 |
+
raise ValueError(
|
| 576 |
+
f"{self} has been incorrectly initialized or {self.__class__} is incorrectly implemented. Expected"
|
| 577 |
+
f" {expected_modules} to be defined, but {components} are defined."
|
| 578 |
+
)
|
| 579 |
+
|
| 580 |
+
return components
|
| 581 |
+
|
| 582 |
+
@staticmethod
|
| 583 |
+
def numpy_to_pil(images):
|
| 584 |
+
"""
|
| 585 |
+
Convert a NumPy image or a batch of images to a PIL image.
|
| 586 |
+
"""
|
| 587 |
+
if images.ndim == 3:
|
| 588 |
+
images = images[None, ...]
|
| 589 |
+
images = (images * 255).round().astype("uint8")
|
| 590 |
+
if images.shape[-1] == 1:
|
| 591 |
+
# special case for grayscale (single channel) images
|
| 592 |
+
pil_images = [Image.fromarray(image.squeeze(), mode="L") for image in images]
|
| 593 |
+
else:
|
| 594 |
+
pil_images = [Image.fromarray(image) for image in images]
|
| 595 |
+
|
| 596 |
+
return pil_images
|
| 597 |
+
|
| 598 |
+
# TODO: make it compatible with jax.lax
|
| 599 |
+
def progress_bar(self, iterable):
|
| 600 |
+
if not hasattr(self, "_progress_bar_config"):
|
| 601 |
+
self._progress_bar_config = {}
|
| 602 |
+
elif not isinstance(self._progress_bar_config, dict):
|
| 603 |
+
raise ValueError(
|
| 604 |
+
f"`self._progress_bar_config` should be of type `dict`, but is {type(self._progress_bar_config)}."
|
| 605 |
+
)
|
| 606 |
+
|
| 607 |
+
return tqdm(iterable, **self._progress_bar_config)
|
| 608 |
+
|
| 609 |
+
def set_progress_bar_config(self, **kwargs):
|
| 610 |
+
self._progress_bar_config = kwargs
|
venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_loading_utils.py
ADDED
|
@@ -0,0 +1,1156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 The HuggingFace Inc. team.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
import importlib
|
| 16 |
+
import os
|
| 17 |
+
import re
|
| 18 |
+
import warnings
|
| 19 |
+
from pathlib import Path
|
| 20 |
+
from typing import Any, Callable, Dict, List, Optional, Union
|
| 21 |
+
|
| 22 |
+
import requests
|
| 23 |
+
import torch
|
| 24 |
+
from huggingface_hub import DDUFEntry, ModelCard, model_info, snapshot_download
|
| 25 |
+
from huggingface_hub.utils import OfflineModeIsEnabled, validate_hf_hub_args
|
| 26 |
+
from packaging import version
|
| 27 |
+
from requests.exceptions import HTTPError
|
| 28 |
+
|
| 29 |
+
from .. import __version__
|
| 30 |
+
from ..utils import (
|
| 31 |
+
FLAX_WEIGHTS_NAME,
|
| 32 |
+
ONNX_EXTERNAL_WEIGHTS_NAME,
|
| 33 |
+
ONNX_WEIGHTS_NAME,
|
| 34 |
+
SAFETENSORS_WEIGHTS_NAME,
|
| 35 |
+
WEIGHTS_NAME,
|
| 36 |
+
deprecate,
|
| 37 |
+
get_class_from_dynamic_module,
|
| 38 |
+
is_accelerate_available,
|
| 39 |
+
is_peft_available,
|
| 40 |
+
is_transformers_available,
|
| 41 |
+
is_transformers_version,
|
| 42 |
+
logging,
|
| 43 |
+
)
|
| 44 |
+
from ..utils.torch_utils import is_compiled_module
|
| 45 |
+
from .transformers_loading_utils import _load_tokenizer_from_dduf, _load_transformers_model_from_dduf
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
if is_transformers_available():
|
| 49 |
+
import transformers
|
| 50 |
+
from transformers import PreTrainedModel, PreTrainedTokenizerBase
|
| 51 |
+
from transformers.utils import FLAX_WEIGHTS_NAME as TRANSFORMERS_FLAX_WEIGHTS_NAME
|
| 52 |
+
from transformers.utils import SAFE_WEIGHTS_NAME as TRANSFORMERS_SAFE_WEIGHTS_NAME
|
| 53 |
+
from transformers.utils import WEIGHTS_NAME as TRANSFORMERS_WEIGHTS_NAME
|
| 54 |
+
|
| 55 |
+
if is_accelerate_available():
|
| 56 |
+
import accelerate
|
| 57 |
+
from accelerate import dispatch_model
|
| 58 |
+
from accelerate.hooks import remove_hook_from_module
|
| 59 |
+
from accelerate.utils import compute_module_sizes, get_max_memory
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
INDEX_FILE = "diffusion_pytorch_model.bin"
|
| 63 |
+
CUSTOM_PIPELINE_FILE_NAME = "pipeline.py"
|
| 64 |
+
DUMMY_MODULES_FOLDER = "diffusers.utils"
|
| 65 |
+
TRANSFORMERS_DUMMY_MODULES_FOLDER = "transformers.utils"
|
| 66 |
+
CONNECTED_PIPES_KEYS = ["prior"]
|
| 67 |
+
|
| 68 |
+
logger = logging.get_logger(__name__)
|
| 69 |
+
|
| 70 |
+
LOADABLE_CLASSES = {
|
| 71 |
+
"diffusers": {
|
| 72 |
+
"ModelMixin": ["save_pretrained", "from_pretrained"],
|
| 73 |
+
"SchedulerMixin": ["save_pretrained", "from_pretrained"],
|
| 74 |
+
"DiffusionPipeline": ["save_pretrained", "from_pretrained"],
|
| 75 |
+
"OnnxRuntimeModel": ["save_pretrained", "from_pretrained"],
|
| 76 |
+
},
|
| 77 |
+
"transformers": {
|
| 78 |
+
"PreTrainedTokenizer": ["save_pretrained", "from_pretrained"],
|
| 79 |
+
"PreTrainedTokenizerFast": ["save_pretrained", "from_pretrained"],
|
| 80 |
+
"PreTrainedModel": ["save_pretrained", "from_pretrained"],
|
| 81 |
+
"FeatureExtractionMixin": ["save_pretrained", "from_pretrained"],
|
| 82 |
+
"ProcessorMixin": ["save_pretrained", "from_pretrained"],
|
| 83 |
+
"ImageProcessingMixin": ["save_pretrained", "from_pretrained"],
|
| 84 |
+
},
|
| 85 |
+
"onnxruntime.training": {
|
| 86 |
+
"ORTModule": ["save_pretrained", "from_pretrained"],
|
| 87 |
+
},
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
ALL_IMPORTABLE_CLASSES = {}
|
| 91 |
+
for library in LOADABLE_CLASSES:
|
| 92 |
+
ALL_IMPORTABLE_CLASSES.update(LOADABLE_CLASSES[library])
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def is_safetensors_compatible(filenames, passed_components=None, folder_names=None, variant=None) -> bool:
|
| 96 |
+
"""
|
| 97 |
+
Checking for safetensors compatibility:
|
| 98 |
+
- The model is safetensors compatible only if there is a safetensors file for each model component present in
|
| 99 |
+
filenames.
|
| 100 |
+
|
| 101 |
+
Converting default pytorch serialized filenames to safetensors serialized filenames:
|
| 102 |
+
- For models from the diffusers library, just replace the ".bin" extension with ".safetensors"
|
| 103 |
+
- For models from the transformers library, the filename changes from "pytorch_model" to "model", and the ".bin"
|
| 104 |
+
extension is replaced with ".safetensors"
|
| 105 |
+
"""
|
| 106 |
+
weight_names = [
|
| 107 |
+
WEIGHTS_NAME,
|
| 108 |
+
SAFETENSORS_WEIGHTS_NAME,
|
| 109 |
+
FLAX_WEIGHTS_NAME,
|
| 110 |
+
ONNX_WEIGHTS_NAME,
|
| 111 |
+
ONNX_EXTERNAL_WEIGHTS_NAME,
|
| 112 |
+
]
|
| 113 |
+
|
| 114 |
+
if is_transformers_available():
|
| 115 |
+
weight_names += [TRANSFORMERS_WEIGHTS_NAME, TRANSFORMERS_SAFE_WEIGHTS_NAME, TRANSFORMERS_FLAX_WEIGHTS_NAME]
|
| 116 |
+
|
| 117 |
+
# model_pytorch, diffusion_model_pytorch, ...
|
| 118 |
+
weight_prefixes = [w.split(".")[0] for w in weight_names]
|
| 119 |
+
# .bin, .safetensors, ...
|
| 120 |
+
weight_suffixs = [w.split(".")[-1] for w in weight_names]
|
| 121 |
+
# -00001-of-00002
|
| 122 |
+
transformers_index_format = r"\d{5}-of-\d{5}"
|
| 123 |
+
# `diffusion_pytorch_model.bin` as well as `model-00001-of-00002.safetensors`
|
| 124 |
+
variant_file_re = re.compile(
|
| 125 |
+
rf"({'|'.join(weight_prefixes)})\.({variant}|{variant}-{transformers_index_format})\.({'|'.join(weight_suffixs)})$"
|
| 126 |
+
)
|
| 127 |
+
non_variant_file_re = re.compile(
|
| 128 |
+
rf"({'|'.join(weight_prefixes)})(-{transformers_index_format})?\.({'|'.join(weight_suffixs)})$"
|
| 129 |
+
)
|
| 130 |
+
|
| 131 |
+
passed_components = passed_components or []
|
| 132 |
+
if folder_names:
|
| 133 |
+
filenames = {f for f in filenames if os.path.split(f)[0] in folder_names}
|
| 134 |
+
|
| 135 |
+
# extract all components of the pipeline and their associated files
|
| 136 |
+
components = {}
|
| 137 |
+
for filename in filenames:
|
| 138 |
+
if not len(filename.split("/")) == 2:
|
| 139 |
+
continue
|
| 140 |
+
|
| 141 |
+
component, component_filename = filename.split("/")
|
| 142 |
+
if component in passed_components:
|
| 143 |
+
continue
|
| 144 |
+
|
| 145 |
+
components.setdefault(component, [])
|
| 146 |
+
components[component].append(component_filename)
|
| 147 |
+
|
| 148 |
+
# If there are no component folders check the main directory for safetensors files
|
| 149 |
+
filtered_filenames = set()
|
| 150 |
+
if not components:
|
| 151 |
+
if variant is not None:
|
| 152 |
+
filtered_filenames = filter_with_regex(filenames, variant_file_re)
|
| 153 |
+
|
| 154 |
+
# If no variant filenames exist check if non-variant files are available
|
| 155 |
+
if not filtered_filenames:
|
| 156 |
+
filtered_filenames = filter_with_regex(filenames, non_variant_file_re)
|
| 157 |
+
return any(".safetensors" in filename for filename in filtered_filenames)
|
| 158 |
+
|
| 159 |
+
# iterate over all files of a component
|
| 160 |
+
# check if safetensor files exist for that component
|
| 161 |
+
for component, component_filenames in components.items():
|
| 162 |
+
matches = []
|
| 163 |
+
filtered_component_filenames = set()
|
| 164 |
+
# if variant is provided check if the variant of the safetensors exists
|
| 165 |
+
if variant is not None:
|
| 166 |
+
filtered_component_filenames = filter_with_regex(component_filenames, variant_file_re)
|
| 167 |
+
|
| 168 |
+
# if variant safetensor files do not exist check for non-variants
|
| 169 |
+
if not filtered_component_filenames:
|
| 170 |
+
filtered_component_filenames = filter_with_regex(component_filenames, non_variant_file_re)
|
| 171 |
+
for component_filename in filtered_component_filenames:
|
| 172 |
+
filename, extension = os.path.splitext(component_filename)
|
| 173 |
+
|
| 174 |
+
match_exists = extension == ".safetensors"
|
| 175 |
+
matches.append(match_exists)
|
| 176 |
+
|
| 177 |
+
if not any(matches):
|
| 178 |
+
return False
|
| 179 |
+
|
| 180 |
+
return True
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def filter_model_files(filenames):
|
| 184 |
+
"""Filter model repo files for just files/folders that contain model weights"""
|
| 185 |
+
weight_names = [
|
| 186 |
+
WEIGHTS_NAME,
|
| 187 |
+
SAFETENSORS_WEIGHTS_NAME,
|
| 188 |
+
FLAX_WEIGHTS_NAME,
|
| 189 |
+
ONNX_WEIGHTS_NAME,
|
| 190 |
+
ONNX_EXTERNAL_WEIGHTS_NAME,
|
| 191 |
+
]
|
| 192 |
+
|
| 193 |
+
if is_transformers_available():
|
| 194 |
+
weight_names += [TRANSFORMERS_WEIGHTS_NAME, TRANSFORMERS_SAFE_WEIGHTS_NAME, TRANSFORMERS_FLAX_WEIGHTS_NAME]
|
| 195 |
+
|
| 196 |
+
allowed_extensions = [wn.split(".")[-1] for wn in weight_names]
|
| 197 |
+
|
| 198 |
+
return [f for f in filenames if any(f.endswith(extension) for extension in allowed_extensions)]
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def filter_with_regex(filenames, pattern_re):
|
| 202 |
+
return {f for f in filenames if pattern_re.match(f.split("/")[-1]) is not None}
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def variant_compatible_siblings(filenames, variant=None, ignore_patterns=None) -> Union[List[os.PathLike], str]:
|
| 206 |
+
weight_names = [
|
| 207 |
+
WEIGHTS_NAME,
|
| 208 |
+
SAFETENSORS_WEIGHTS_NAME,
|
| 209 |
+
FLAX_WEIGHTS_NAME,
|
| 210 |
+
ONNX_WEIGHTS_NAME,
|
| 211 |
+
ONNX_EXTERNAL_WEIGHTS_NAME,
|
| 212 |
+
]
|
| 213 |
+
|
| 214 |
+
if is_transformers_available():
|
| 215 |
+
weight_names += [TRANSFORMERS_WEIGHTS_NAME, TRANSFORMERS_SAFE_WEIGHTS_NAME, TRANSFORMERS_FLAX_WEIGHTS_NAME]
|
| 216 |
+
|
| 217 |
+
# model_pytorch, diffusion_model_pytorch, ...
|
| 218 |
+
weight_prefixes = [w.split(".")[0] for w in weight_names]
|
| 219 |
+
# .bin, .safetensors, ...
|
| 220 |
+
weight_suffixs = [w.split(".")[-1] for w in weight_names]
|
| 221 |
+
# -00001-of-00002
|
| 222 |
+
transformers_index_format = r"\d{5}-of-\d{5}"
|
| 223 |
+
|
| 224 |
+
if variant is not None:
|
| 225 |
+
# `diffusion_pytorch_model.fp16.bin` as well as `model.fp16-00001-of-00002.safetensors`
|
| 226 |
+
variant_file_re = re.compile(
|
| 227 |
+
rf"({'|'.join(weight_prefixes)})\.({variant}|{variant}-{transformers_index_format})\.({'|'.join(weight_suffixs)})$"
|
| 228 |
+
)
|
| 229 |
+
# `text_encoder/pytorch_model.bin.index.fp16.json`
|
| 230 |
+
variant_index_re = re.compile(
|
| 231 |
+
rf"({'|'.join(weight_prefixes)})\.({'|'.join(weight_suffixs)})\.index\.{variant}\.json$"
|
| 232 |
+
)
|
| 233 |
+
legacy_variant_file_re = re.compile(rf".*-{transformers_index_format}\.{variant}\.[a-z]+$")
|
| 234 |
+
legacy_variant_index_re = re.compile(
|
| 235 |
+
rf"({'|'.join(weight_prefixes)})\.({'|'.join(weight_suffixs)})\.{variant}\.index\.json$"
|
| 236 |
+
)
|
| 237 |
+
|
| 238 |
+
# `diffusion_pytorch_model.bin` as well as `model-00001-of-00002.safetensors`
|
| 239 |
+
non_variant_file_re = re.compile(
|
| 240 |
+
rf"({'|'.join(weight_prefixes)})(-{transformers_index_format})?\.({'|'.join(weight_suffixs)})$"
|
| 241 |
+
)
|
| 242 |
+
# `text_encoder/pytorch_model.bin.index.json`
|
| 243 |
+
non_variant_index_re = re.compile(rf"({'|'.join(weight_prefixes)})\.({'|'.join(weight_suffixs)})\.index\.json")
|
| 244 |
+
|
| 245 |
+
def filter_for_compatible_extensions(filenames, ignore_patterns=None):
|
| 246 |
+
if not ignore_patterns:
|
| 247 |
+
return filenames
|
| 248 |
+
|
| 249 |
+
# ignore patterns uses glob style patterns e.g *.safetensors but we're only
|
| 250 |
+
# interested in the extension name
|
| 251 |
+
return {f for f in filenames if not any(f.endswith(pat.lstrip("*.")) for pat in ignore_patterns)}
|
| 252 |
+
|
| 253 |
+
# Group files by component
|
| 254 |
+
components = {}
|
| 255 |
+
for filename in filenames:
|
| 256 |
+
if not len(filename.split("/")) == 2:
|
| 257 |
+
components.setdefault("", []).append(filename)
|
| 258 |
+
continue
|
| 259 |
+
|
| 260 |
+
component, _ = filename.split("/")
|
| 261 |
+
components.setdefault(component, []).append(filename)
|
| 262 |
+
|
| 263 |
+
usable_filenames = set()
|
| 264 |
+
variant_filenames = set()
|
| 265 |
+
for component, component_filenames in components.items():
|
| 266 |
+
component_filenames = filter_for_compatible_extensions(component_filenames, ignore_patterns=ignore_patterns)
|
| 267 |
+
|
| 268 |
+
component_variants = set()
|
| 269 |
+
component_legacy_variants = set()
|
| 270 |
+
component_non_variants = set()
|
| 271 |
+
if variant is not None:
|
| 272 |
+
component_variants = filter_with_regex(component_filenames, variant_file_re)
|
| 273 |
+
component_variant_index_files = filter_with_regex(component_filenames, variant_index_re)
|
| 274 |
+
|
| 275 |
+
component_legacy_variants = filter_with_regex(component_filenames, legacy_variant_file_re)
|
| 276 |
+
component_legacy_variant_index_files = filter_with_regex(component_filenames, legacy_variant_index_re)
|
| 277 |
+
|
| 278 |
+
if component_variants or component_legacy_variants:
|
| 279 |
+
variant_filenames.update(
|
| 280 |
+
component_variants | component_variant_index_files
|
| 281 |
+
if component_variants
|
| 282 |
+
else component_legacy_variants | component_legacy_variant_index_files
|
| 283 |
+
)
|
| 284 |
+
|
| 285 |
+
else:
|
| 286 |
+
component_non_variants = filter_with_regex(component_filenames, non_variant_file_re)
|
| 287 |
+
component_variant_index_files = filter_with_regex(component_filenames, non_variant_index_re)
|
| 288 |
+
|
| 289 |
+
usable_filenames.update(component_non_variants | component_variant_index_files)
|
| 290 |
+
|
| 291 |
+
usable_filenames.update(variant_filenames)
|
| 292 |
+
|
| 293 |
+
if len(variant_filenames) == 0 and variant is not None:
|
| 294 |
+
error_message = f"You are trying to load model files of the `variant={variant}`, but no such modeling files are available. "
|
| 295 |
+
raise ValueError(error_message)
|
| 296 |
+
|
| 297 |
+
if len(variant_filenames) > 0 and usable_filenames != variant_filenames:
|
| 298 |
+
logger.warning(
|
| 299 |
+
f"\nA mixture of {variant} and non-{variant} filenames will be loaded.\nLoaded {variant} filenames:\n"
|
| 300 |
+
f"[{', '.join(variant_filenames)}]\nLoaded non-{variant} filenames:\n"
|
| 301 |
+
f"[{', '.join(usable_filenames - variant_filenames)}\nIf this behavior is not "
|
| 302 |
+
f"expected, please check your folder structure."
|
| 303 |
+
)
|
| 304 |
+
|
| 305 |
+
return usable_filenames, variant_filenames
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
@validate_hf_hub_args
|
| 309 |
+
def warn_deprecated_model_variant(pretrained_model_name_or_path, token, variant, revision, model_filenames):
|
| 310 |
+
info = model_info(
|
| 311 |
+
pretrained_model_name_or_path,
|
| 312 |
+
token=token,
|
| 313 |
+
revision=None,
|
| 314 |
+
)
|
| 315 |
+
filenames = {sibling.rfilename for sibling in info.siblings}
|
| 316 |
+
comp_model_filenames, _ = variant_compatible_siblings(filenames, variant=revision)
|
| 317 |
+
comp_model_filenames = [".".join(f.split(".")[:1] + f.split(".")[2:]) for f in comp_model_filenames]
|
| 318 |
+
|
| 319 |
+
if set(model_filenames).issubset(set(comp_model_filenames)):
|
| 320 |
+
warnings.warn(
|
| 321 |
+
f"You are loading the variant {revision} from {pretrained_model_name_or_path} via `revision='{revision}'` even though you can load it via `variant=`{revision}`. Loading model variants via `revision='{revision}'` is deprecated and will be removed in diffusers v1. Please use `variant='{revision}'` instead.",
|
| 322 |
+
FutureWarning,
|
| 323 |
+
)
|
| 324 |
+
else:
|
| 325 |
+
warnings.warn(
|
| 326 |
+
f"You are loading the variant {revision} from {pretrained_model_name_or_path} via `revision='{revision}'`. This behavior is deprecated and will be removed in diffusers v1. One should use `variant='{revision}'` instead. However, it appears that {pretrained_model_name_or_path} currently does not have the required variant filenames in the 'main' branch. \n The Diffusers team and community would be very grateful if you could open an issue: https://github.com/huggingface/diffusers/issues/new with the title '{pretrained_model_name_or_path} is missing {revision} files' so that the correct variant file can be added.",
|
| 327 |
+
FutureWarning,
|
| 328 |
+
)
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
def _unwrap_model(model):
|
| 332 |
+
"""Unwraps a model."""
|
| 333 |
+
if is_compiled_module(model):
|
| 334 |
+
model = model._orig_mod
|
| 335 |
+
|
| 336 |
+
if is_peft_available():
|
| 337 |
+
from peft import PeftModel
|
| 338 |
+
|
| 339 |
+
if isinstance(model, PeftModel):
|
| 340 |
+
model = model.base_model.model
|
| 341 |
+
|
| 342 |
+
return model
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
def maybe_raise_or_warn(
|
| 346 |
+
library_name, library, class_name, importable_classes, passed_class_obj, name, is_pipeline_module
|
| 347 |
+
):
|
| 348 |
+
"""Simple helper method to raise or warn in case incorrect module has been passed"""
|
| 349 |
+
if not is_pipeline_module:
|
| 350 |
+
library = importlib.import_module(library_name)
|
| 351 |
+
class_obj = getattr(library, class_name)
|
| 352 |
+
class_candidates = {c: getattr(library, c, None) for c in importable_classes.keys()}
|
| 353 |
+
|
| 354 |
+
expected_class_obj = None
|
| 355 |
+
for class_name, class_candidate in class_candidates.items():
|
| 356 |
+
if class_candidate is not None and issubclass(class_obj, class_candidate):
|
| 357 |
+
expected_class_obj = class_candidate
|
| 358 |
+
|
| 359 |
+
# Dynamo wraps the original model in a private class.
|
| 360 |
+
# I didn't find a public API to get the original class.
|
| 361 |
+
sub_model = passed_class_obj[name]
|
| 362 |
+
unwrapped_sub_model = _unwrap_model(sub_model)
|
| 363 |
+
model_cls = unwrapped_sub_model.__class__
|
| 364 |
+
|
| 365 |
+
if not issubclass(model_cls, expected_class_obj):
|
| 366 |
+
raise ValueError(f"{passed_class_obj[name]} is of type: {model_cls}, but should be {expected_class_obj}")
|
| 367 |
+
else:
|
| 368 |
+
logger.warning(
|
| 369 |
+
f"You have passed a non-standard module {passed_class_obj[name]}. We cannot verify whether it"
|
| 370 |
+
" has the correct type"
|
| 371 |
+
)
|
| 372 |
+
|
| 373 |
+
|
| 374 |
+
def get_class_obj_and_candidates(
|
| 375 |
+
library_name, class_name, importable_classes, pipelines, is_pipeline_module, component_name=None, cache_dir=None
|
| 376 |
+
):
|
| 377 |
+
"""Simple helper method to retrieve class object of module as well as potential parent class objects"""
|
| 378 |
+
component_folder = os.path.join(cache_dir, component_name) if component_name and cache_dir else None
|
| 379 |
+
|
| 380 |
+
if is_pipeline_module:
|
| 381 |
+
pipeline_module = getattr(pipelines, library_name)
|
| 382 |
+
|
| 383 |
+
class_obj = getattr(pipeline_module, class_name)
|
| 384 |
+
class_candidates = dict.fromkeys(importable_classes.keys(), class_obj)
|
| 385 |
+
elif component_folder and os.path.isfile(os.path.join(component_folder, library_name + ".py")):
|
| 386 |
+
# load custom component
|
| 387 |
+
class_obj = get_class_from_dynamic_module(
|
| 388 |
+
component_folder, module_file=library_name + ".py", class_name=class_name
|
| 389 |
+
)
|
| 390 |
+
class_candidates = dict.fromkeys(importable_classes.keys(), class_obj)
|
| 391 |
+
else:
|
| 392 |
+
# else we just import it from the library.
|
| 393 |
+
library = importlib.import_module(library_name)
|
| 394 |
+
|
| 395 |
+
class_obj = getattr(library, class_name)
|
| 396 |
+
class_candidates = {c: getattr(library, c, None) for c in importable_classes.keys()}
|
| 397 |
+
|
| 398 |
+
return class_obj, class_candidates
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
def _get_custom_pipeline_class(
|
| 402 |
+
custom_pipeline,
|
| 403 |
+
repo_id=None,
|
| 404 |
+
hub_revision=None,
|
| 405 |
+
class_name=None,
|
| 406 |
+
cache_dir=None,
|
| 407 |
+
revision=None,
|
| 408 |
+
):
|
| 409 |
+
if custom_pipeline.endswith(".py"):
|
| 410 |
+
path = Path(custom_pipeline)
|
| 411 |
+
# decompose into folder & file
|
| 412 |
+
file_name = path.name
|
| 413 |
+
custom_pipeline = path.parent.absolute()
|
| 414 |
+
elif repo_id is not None:
|
| 415 |
+
file_name = f"{custom_pipeline}.py"
|
| 416 |
+
custom_pipeline = repo_id
|
| 417 |
+
else:
|
| 418 |
+
file_name = CUSTOM_PIPELINE_FILE_NAME
|
| 419 |
+
|
| 420 |
+
if repo_id is not None and hub_revision is not None:
|
| 421 |
+
# if we load the pipeline code from the Hub
|
| 422 |
+
# make sure to overwrite the `revision`
|
| 423 |
+
revision = hub_revision
|
| 424 |
+
|
| 425 |
+
return get_class_from_dynamic_module(
|
| 426 |
+
custom_pipeline,
|
| 427 |
+
module_file=file_name,
|
| 428 |
+
class_name=class_name,
|
| 429 |
+
cache_dir=cache_dir,
|
| 430 |
+
revision=revision,
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
+
|
| 434 |
+
def _get_pipeline_class(
|
| 435 |
+
class_obj,
|
| 436 |
+
config=None,
|
| 437 |
+
load_connected_pipeline=False,
|
| 438 |
+
custom_pipeline=None,
|
| 439 |
+
repo_id=None,
|
| 440 |
+
hub_revision=None,
|
| 441 |
+
class_name=None,
|
| 442 |
+
cache_dir=None,
|
| 443 |
+
revision=None,
|
| 444 |
+
):
|
| 445 |
+
if custom_pipeline is not None:
|
| 446 |
+
return _get_custom_pipeline_class(
|
| 447 |
+
custom_pipeline,
|
| 448 |
+
repo_id=repo_id,
|
| 449 |
+
hub_revision=hub_revision,
|
| 450 |
+
class_name=class_name,
|
| 451 |
+
cache_dir=cache_dir,
|
| 452 |
+
revision=revision,
|
| 453 |
+
)
|
| 454 |
+
|
| 455 |
+
if class_obj.__name__ != "DiffusionPipeline":
|
| 456 |
+
return class_obj
|
| 457 |
+
|
| 458 |
+
diffusers_module = importlib.import_module(class_obj.__module__.split(".")[0])
|
| 459 |
+
class_name = class_name or config["_class_name"]
|
| 460 |
+
if not class_name:
|
| 461 |
+
raise ValueError(
|
| 462 |
+
"The class name could not be found in the configuration file. Please make sure to pass the correct `class_name`."
|
| 463 |
+
)
|
| 464 |
+
|
| 465 |
+
class_name = class_name[4:] if class_name.startswith("Flax") else class_name
|
| 466 |
+
|
| 467 |
+
pipeline_cls = getattr(diffusers_module, class_name)
|
| 468 |
+
|
| 469 |
+
if load_connected_pipeline:
|
| 470 |
+
from .auto_pipeline import _get_connected_pipeline
|
| 471 |
+
|
| 472 |
+
connected_pipeline_cls = _get_connected_pipeline(pipeline_cls)
|
| 473 |
+
if connected_pipeline_cls is not None:
|
| 474 |
+
logger.info(
|
| 475 |
+
f"Loading connected pipeline {connected_pipeline_cls.__name__} instead of {pipeline_cls.__name__} as specified via `load_connected_pipeline=True`"
|
| 476 |
+
)
|
| 477 |
+
else:
|
| 478 |
+
logger.info(f"{pipeline_cls.__name__} has no connected pipeline class. Loading {pipeline_cls.__name__}.")
|
| 479 |
+
|
| 480 |
+
pipeline_cls = connected_pipeline_cls or pipeline_cls
|
| 481 |
+
|
| 482 |
+
return pipeline_cls
|
| 483 |
+
|
| 484 |
+
|
| 485 |
+
def _load_empty_model(
|
| 486 |
+
library_name: str,
|
| 487 |
+
class_name: str,
|
| 488 |
+
importable_classes: List[Any],
|
| 489 |
+
pipelines: Any,
|
| 490 |
+
is_pipeline_module: bool,
|
| 491 |
+
name: str,
|
| 492 |
+
torch_dtype: Union[str, torch.dtype],
|
| 493 |
+
cached_folder: Union[str, os.PathLike],
|
| 494 |
+
**kwargs,
|
| 495 |
+
):
|
| 496 |
+
# retrieve class objects.
|
| 497 |
+
class_obj, _ = get_class_obj_and_candidates(
|
| 498 |
+
library_name,
|
| 499 |
+
class_name,
|
| 500 |
+
importable_classes,
|
| 501 |
+
pipelines,
|
| 502 |
+
is_pipeline_module,
|
| 503 |
+
component_name=name,
|
| 504 |
+
cache_dir=cached_folder,
|
| 505 |
+
)
|
| 506 |
+
|
| 507 |
+
if is_transformers_available():
|
| 508 |
+
transformers_version = version.parse(version.parse(transformers.__version__).base_version)
|
| 509 |
+
else:
|
| 510 |
+
transformers_version = "N/A"
|
| 511 |
+
|
| 512 |
+
# Determine library.
|
| 513 |
+
is_transformers_model = (
|
| 514 |
+
is_transformers_available()
|
| 515 |
+
and issubclass(class_obj, PreTrainedModel)
|
| 516 |
+
and transformers_version >= version.parse("4.20.0")
|
| 517 |
+
)
|
| 518 |
+
diffusers_module = importlib.import_module(__name__.split(".")[0])
|
| 519 |
+
is_diffusers_model = issubclass(class_obj, diffusers_module.ModelMixin)
|
| 520 |
+
|
| 521 |
+
model = None
|
| 522 |
+
config_path = cached_folder
|
| 523 |
+
user_agent = {
|
| 524 |
+
"diffusers": __version__,
|
| 525 |
+
"file_type": "model",
|
| 526 |
+
"framework": "pytorch",
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
if is_diffusers_model:
|
| 530 |
+
# Load config and then the model on meta.
|
| 531 |
+
config, unused_kwargs, commit_hash = class_obj.load_config(
|
| 532 |
+
os.path.join(config_path, name),
|
| 533 |
+
cache_dir=cached_folder,
|
| 534 |
+
return_unused_kwargs=True,
|
| 535 |
+
return_commit_hash=True,
|
| 536 |
+
force_download=kwargs.pop("force_download", False),
|
| 537 |
+
proxies=kwargs.pop("proxies", None),
|
| 538 |
+
local_files_only=kwargs.pop("local_files_only", False),
|
| 539 |
+
token=kwargs.pop("token", None),
|
| 540 |
+
revision=kwargs.pop("revision", None),
|
| 541 |
+
subfolder=kwargs.pop("subfolder", None),
|
| 542 |
+
user_agent=user_agent,
|
| 543 |
+
)
|
| 544 |
+
with accelerate.init_empty_weights():
|
| 545 |
+
model = class_obj.from_config(config, **unused_kwargs)
|
| 546 |
+
elif is_transformers_model:
|
| 547 |
+
config_class = getattr(class_obj, "config_class", None)
|
| 548 |
+
if config_class is None:
|
| 549 |
+
raise ValueError("`config_class` cannot be None. Please double-check the model.")
|
| 550 |
+
|
| 551 |
+
config = config_class.from_pretrained(
|
| 552 |
+
cached_folder,
|
| 553 |
+
subfolder=name,
|
| 554 |
+
force_download=kwargs.pop("force_download", False),
|
| 555 |
+
proxies=kwargs.pop("proxies", None),
|
| 556 |
+
local_files_only=kwargs.pop("local_files_only", False),
|
| 557 |
+
token=kwargs.pop("token", None),
|
| 558 |
+
revision=kwargs.pop("revision", None),
|
| 559 |
+
user_agent=user_agent,
|
| 560 |
+
)
|
| 561 |
+
with accelerate.init_empty_weights():
|
| 562 |
+
model = class_obj(config)
|
| 563 |
+
|
| 564 |
+
if model is not None:
|
| 565 |
+
model = model.to(dtype=torch_dtype)
|
| 566 |
+
return model
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
def _assign_components_to_devices(
|
| 570 |
+
module_sizes: Dict[str, float], device_memory: Dict[str, float], device_mapping_strategy: str = "balanced"
|
| 571 |
+
):
|
| 572 |
+
device_ids = list(device_memory.keys())
|
| 573 |
+
device_cycle = device_ids + device_ids[::-1]
|
| 574 |
+
device_memory = device_memory.copy()
|
| 575 |
+
|
| 576 |
+
device_id_component_mapping = {}
|
| 577 |
+
current_device_index = 0
|
| 578 |
+
for component in module_sizes:
|
| 579 |
+
device_id = device_cycle[current_device_index % len(device_cycle)]
|
| 580 |
+
component_memory = module_sizes[component]
|
| 581 |
+
curr_device_memory = device_memory[device_id]
|
| 582 |
+
|
| 583 |
+
# If the GPU doesn't fit the current component offload to the CPU.
|
| 584 |
+
if component_memory > curr_device_memory:
|
| 585 |
+
device_id_component_mapping["cpu"] = [component]
|
| 586 |
+
else:
|
| 587 |
+
if device_id not in device_id_component_mapping:
|
| 588 |
+
device_id_component_mapping[device_id] = [component]
|
| 589 |
+
else:
|
| 590 |
+
device_id_component_mapping[device_id].append(component)
|
| 591 |
+
|
| 592 |
+
# Update the device memory.
|
| 593 |
+
device_memory[device_id] -= component_memory
|
| 594 |
+
current_device_index += 1
|
| 595 |
+
|
| 596 |
+
return device_id_component_mapping
|
| 597 |
+
|
| 598 |
+
|
| 599 |
+
def _get_final_device_map(device_map, pipeline_class, passed_class_obj, init_dict, library, max_memory, **kwargs):
|
| 600 |
+
# To avoid circular import problem.
|
| 601 |
+
from diffusers import pipelines
|
| 602 |
+
|
| 603 |
+
torch_dtype = kwargs.get("torch_dtype", torch.float32)
|
| 604 |
+
|
| 605 |
+
# Load each module in the pipeline on a meta device so that we can derive the device map.
|
| 606 |
+
init_empty_modules = {}
|
| 607 |
+
for name, (library_name, class_name) in init_dict.items():
|
| 608 |
+
if class_name.startswith("Flax"):
|
| 609 |
+
raise ValueError("Flax pipelines are not supported with `device_map`.")
|
| 610 |
+
|
| 611 |
+
# Define all importable classes
|
| 612 |
+
is_pipeline_module = hasattr(pipelines, library_name)
|
| 613 |
+
importable_classes = ALL_IMPORTABLE_CLASSES
|
| 614 |
+
loaded_sub_model = None
|
| 615 |
+
|
| 616 |
+
# Use passed sub model or load class_name from library_name
|
| 617 |
+
if name in passed_class_obj:
|
| 618 |
+
# if the model is in a pipeline module, then we load it from the pipeline
|
| 619 |
+
# check that passed_class_obj has correct parent class
|
| 620 |
+
maybe_raise_or_warn(
|
| 621 |
+
library_name,
|
| 622 |
+
library,
|
| 623 |
+
class_name,
|
| 624 |
+
importable_classes,
|
| 625 |
+
passed_class_obj,
|
| 626 |
+
name,
|
| 627 |
+
is_pipeline_module,
|
| 628 |
+
)
|
| 629 |
+
with accelerate.init_empty_weights():
|
| 630 |
+
loaded_sub_model = passed_class_obj[name]
|
| 631 |
+
|
| 632 |
+
else:
|
| 633 |
+
sub_model_dtype = (
|
| 634 |
+
torch_dtype.get(name, torch_dtype.get("default", torch.float32))
|
| 635 |
+
if isinstance(torch_dtype, dict)
|
| 636 |
+
else torch_dtype
|
| 637 |
+
)
|
| 638 |
+
loaded_sub_model = _load_empty_model(
|
| 639 |
+
library_name=library_name,
|
| 640 |
+
class_name=class_name,
|
| 641 |
+
importable_classes=importable_classes,
|
| 642 |
+
pipelines=pipelines,
|
| 643 |
+
is_pipeline_module=is_pipeline_module,
|
| 644 |
+
pipeline_class=pipeline_class,
|
| 645 |
+
name=name,
|
| 646 |
+
torch_dtype=sub_model_dtype,
|
| 647 |
+
cached_folder=kwargs.get("cached_folder", None),
|
| 648 |
+
force_download=kwargs.get("force_download", None),
|
| 649 |
+
proxies=kwargs.get("proxies", None),
|
| 650 |
+
local_files_only=kwargs.get("local_files_only", None),
|
| 651 |
+
token=kwargs.get("token", None),
|
| 652 |
+
revision=kwargs.get("revision", None),
|
| 653 |
+
)
|
| 654 |
+
|
| 655 |
+
if loaded_sub_model is not None:
|
| 656 |
+
init_empty_modules[name] = loaded_sub_model
|
| 657 |
+
|
| 658 |
+
# determine device map
|
| 659 |
+
# Obtain a sorted dictionary for mapping the model-level components
|
| 660 |
+
# to their sizes.
|
| 661 |
+
module_sizes = {
|
| 662 |
+
module_name: compute_module_sizes(
|
| 663 |
+
module,
|
| 664 |
+
dtype=torch_dtype.get(module_name, torch_dtype.get("default", torch.float32))
|
| 665 |
+
if isinstance(torch_dtype, dict)
|
| 666 |
+
else torch_dtype,
|
| 667 |
+
)[""]
|
| 668 |
+
for module_name, module in init_empty_modules.items()
|
| 669 |
+
if isinstance(module, torch.nn.Module)
|
| 670 |
+
}
|
| 671 |
+
module_sizes = dict(sorted(module_sizes.items(), key=lambda item: item[1], reverse=True))
|
| 672 |
+
|
| 673 |
+
# Obtain maximum memory available per device (GPUs only).
|
| 674 |
+
max_memory = get_max_memory(max_memory)
|
| 675 |
+
max_memory = dict(sorted(max_memory.items(), key=lambda item: item[1], reverse=True))
|
| 676 |
+
max_memory = {k: v for k, v in max_memory.items() if k != "cpu"}
|
| 677 |
+
|
| 678 |
+
# Obtain a dictionary mapping the model-level components to the available
|
| 679 |
+
# devices based on the maximum memory and the model sizes.
|
| 680 |
+
final_device_map = None
|
| 681 |
+
if len(max_memory) > 0:
|
| 682 |
+
device_id_component_mapping = _assign_components_to_devices(
|
| 683 |
+
module_sizes, max_memory, device_mapping_strategy=device_map
|
| 684 |
+
)
|
| 685 |
+
|
| 686 |
+
# Obtain the final device map, e.g., `{"unet": 0, "text_encoder": 1, "vae": 1, ...}`
|
| 687 |
+
final_device_map = {}
|
| 688 |
+
for device_id, components in device_id_component_mapping.items():
|
| 689 |
+
for component in components:
|
| 690 |
+
final_device_map[component] = device_id
|
| 691 |
+
|
| 692 |
+
return final_device_map
|
| 693 |
+
|
| 694 |
+
|
| 695 |
+
def load_sub_model(
|
| 696 |
+
library_name: str,
|
| 697 |
+
class_name: str,
|
| 698 |
+
importable_classes: List[Any],
|
| 699 |
+
pipelines: Any,
|
| 700 |
+
is_pipeline_module: bool,
|
| 701 |
+
pipeline_class: Any,
|
| 702 |
+
torch_dtype: torch.dtype,
|
| 703 |
+
provider: Any,
|
| 704 |
+
sess_options: Any,
|
| 705 |
+
device_map: Optional[Union[Dict[str, torch.device], str]],
|
| 706 |
+
max_memory: Optional[Dict[Union[int, str], Union[int, str]]],
|
| 707 |
+
offload_folder: Optional[Union[str, os.PathLike]],
|
| 708 |
+
offload_state_dict: bool,
|
| 709 |
+
model_variants: Dict[str, str],
|
| 710 |
+
name: str,
|
| 711 |
+
from_flax: bool,
|
| 712 |
+
variant: str,
|
| 713 |
+
low_cpu_mem_usage: bool,
|
| 714 |
+
cached_folder: Union[str, os.PathLike],
|
| 715 |
+
use_safetensors: bool,
|
| 716 |
+
dduf_entries: Optional[Dict[str, DDUFEntry]],
|
| 717 |
+
provider_options: Any,
|
| 718 |
+
quantization_config: Optional[Any] = None,
|
| 719 |
+
):
|
| 720 |
+
"""Helper method to load the module `name` from `library_name` and `class_name`"""
|
| 721 |
+
from ..quantizers import PipelineQuantizationConfig
|
| 722 |
+
|
| 723 |
+
# retrieve class candidates
|
| 724 |
+
|
| 725 |
+
class_obj, class_candidates = get_class_obj_and_candidates(
|
| 726 |
+
library_name,
|
| 727 |
+
class_name,
|
| 728 |
+
importable_classes,
|
| 729 |
+
pipelines,
|
| 730 |
+
is_pipeline_module,
|
| 731 |
+
component_name=name,
|
| 732 |
+
cache_dir=cached_folder,
|
| 733 |
+
)
|
| 734 |
+
|
| 735 |
+
load_method_name = None
|
| 736 |
+
# retrieve load method name
|
| 737 |
+
for class_name, class_candidate in class_candidates.items():
|
| 738 |
+
if class_candidate is not None and issubclass(class_obj, class_candidate):
|
| 739 |
+
load_method_name = importable_classes[class_name][1]
|
| 740 |
+
|
| 741 |
+
# if load method name is None, then we have a dummy module -> raise Error
|
| 742 |
+
if load_method_name is None:
|
| 743 |
+
none_module = class_obj.__module__
|
| 744 |
+
is_dummy_path = none_module.startswith(DUMMY_MODULES_FOLDER) or none_module.startswith(
|
| 745 |
+
TRANSFORMERS_DUMMY_MODULES_FOLDER
|
| 746 |
+
)
|
| 747 |
+
if is_dummy_path and "dummy" in none_module:
|
| 748 |
+
# call class_obj for nice error message of missing requirements
|
| 749 |
+
class_obj()
|
| 750 |
+
|
| 751 |
+
raise ValueError(
|
| 752 |
+
f"The component {class_obj} of {pipeline_class} cannot be loaded as it does not seem to have"
|
| 753 |
+
f" any of the loading methods defined in {ALL_IMPORTABLE_CLASSES}."
|
| 754 |
+
)
|
| 755 |
+
|
| 756 |
+
load_method = _get_load_method(class_obj, load_method_name, is_dduf=dduf_entries is not None)
|
| 757 |
+
|
| 758 |
+
# add kwargs to loading method
|
| 759 |
+
diffusers_module = importlib.import_module(__name__.split(".")[0])
|
| 760 |
+
loading_kwargs = {}
|
| 761 |
+
if issubclass(class_obj, torch.nn.Module):
|
| 762 |
+
loading_kwargs["torch_dtype"] = torch_dtype
|
| 763 |
+
if issubclass(class_obj, diffusers_module.OnnxRuntimeModel):
|
| 764 |
+
loading_kwargs["provider"] = provider
|
| 765 |
+
loading_kwargs["sess_options"] = sess_options
|
| 766 |
+
loading_kwargs["provider_options"] = provider_options
|
| 767 |
+
|
| 768 |
+
is_diffusers_model = issubclass(class_obj, diffusers_module.ModelMixin)
|
| 769 |
+
|
| 770 |
+
if is_transformers_available():
|
| 771 |
+
transformers_version = version.parse(version.parse(transformers.__version__).base_version)
|
| 772 |
+
else:
|
| 773 |
+
transformers_version = "N/A"
|
| 774 |
+
|
| 775 |
+
is_transformers_model = (
|
| 776 |
+
is_transformers_available()
|
| 777 |
+
and issubclass(class_obj, PreTrainedModel)
|
| 778 |
+
and transformers_version >= version.parse("4.20.0")
|
| 779 |
+
)
|
| 780 |
+
|
| 781 |
+
# When loading a transformers model, if the device_map is None, the weights will be initialized as opposed to diffusers.
|
| 782 |
+
# To make default loading faster we set the `low_cpu_mem_usage=low_cpu_mem_usage` flag which is `True` by default.
|
| 783 |
+
# This makes sure that the weights won't be initialized which significantly speeds up loading.
|
| 784 |
+
if is_diffusers_model or is_transformers_model:
|
| 785 |
+
loading_kwargs["device_map"] = device_map
|
| 786 |
+
loading_kwargs["max_memory"] = max_memory
|
| 787 |
+
loading_kwargs["offload_folder"] = offload_folder
|
| 788 |
+
loading_kwargs["offload_state_dict"] = offload_state_dict
|
| 789 |
+
loading_kwargs["variant"] = model_variants.pop(name, None)
|
| 790 |
+
loading_kwargs["use_safetensors"] = use_safetensors
|
| 791 |
+
|
| 792 |
+
if from_flax:
|
| 793 |
+
loading_kwargs["from_flax"] = True
|
| 794 |
+
|
| 795 |
+
# the following can be deleted once the minimum required `transformers` version
|
| 796 |
+
# is higher than 4.27
|
| 797 |
+
if (
|
| 798 |
+
is_transformers_model
|
| 799 |
+
and loading_kwargs["variant"] is not None
|
| 800 |
+
and transformers_version < version.parse("4.27.0")
|
| 801 |
+
):
|
| 802 |
+
raise ImportError(
|
| 803 |
+
f"When passing `variant='{variant}'`, please make sure to upgrade your `transformers` version to at least 4.27.0.dev0"
|
| 804 |
+
)
|
| 805 |
+
elif is_transformers_model and loading_kwargs["variant"] is None:
|
| 806 |
+
loading_kwargs.pop("variant")
|
| 807 |
+
|
| 808 |
+
# if `from_flax` and model is transformer model, can currently not load with `low_cpu_mem_usage`
|
| 809 |
+
if not (from_flax and is_transformers_model):
|
| 810 |
+
loading_kwargs["low_cpu_mem_usage"] = low_cpu_mem_usage
|
| 811 |
+
else:
|
| 812 |
+
loading_kwargs["low_cpu_mem_usage"] = False
|
| 813 |
+
|
| 814 |
+
if (
|
| 815 |
+
quantization_config is not None
|
| 816 |
+
and isinstance(quantization_config, PipelineQuantizationConfig)
|
| 817 |
+
and issubclass(class_obj, torch.nn.Module)
|
| 818 |
+
):
|
| 819 |
+
model_quant_config = quantization_config._resolve_quant_config(
|
| 820 |
+
is_diffusers=is_diffusers_model, module_name=name
|
| 821 |
+
)
|
| 822 |
+
if model_quant_config is not None:
|
| 823 |
+
loading_kwargs["quantization_config"] = model_quant_config
|
| 824 |
+
|
| 825 |
+
# check if the module is in a subdirectory
|
| 826 |
+
if dduf_entries:
|
| 827 |
+
loading_kwargs["dduf_entries"] = dduf_entries
|
| 828 |
+
loaded_sub_model = load_method(name, **loading_kwargs)
|
| 829 |
+
elif os.path.isdir(os.path.join(cached_folder, name)):
|
| 830 |
+
loaded_sub_model = load_method(os.path.join(cached_folder, name), **loading_kwargs)
|
| 831 |
+
else:
|
| 832 |
+
# else load from the root directory
|
| 833 |
+
loaded_sub_model = load_method(cached_folder, **loading_kwargs)
|
| 834 |
+
|
| 835 |
+
if isinstance(loaded_sub_model, torch.nn.Module) and isinstance(device_map, dict):
|
| 836 |
+
# remove hooks
|
| 837 |
+
remove_hook_from_module(loaded_sub_model, recurse=True)
|
| 838 |
+
needs_offloading_to_cpu = device_map[""] == "cpu"
|
| 839 |
+
|
| 840 |
+
if needs_offloading_to_cpu:
|
| 841 |
+
dispatch_model(
|
| 842 |
+
loaded_sub_model,
|
| 843 |
+
state_dict=loaded_sub_model.state_dict(),
|
| 844 |
+
device_map=device_map,
|
| 845 |
+
force_hooks=True,
|
| 846 |
+
main_device=0,
|
| 847 |
+
)
|
| 848 |
+
else:
|
| 849 |
+
dispatch_model(loaded_sub_model, device_map=device_map, force_hooks=True)
|
| 850 |
+
|
| 851 |
+
return loaded_sub_model
|
| 852 |
+
|
| 853 |
+
|
| 854 |
+
def _get_load_method(class_obj: object, load_method_name: str, is_dduf: bool) -> Callable:
|
| 855 |
+
"""
|
| 856 |
+
Return the method to load the sub model.
|
| 857 |
+
|
| 858 |
+
In practice, this method will return the `"from_pretrained"` (or `load_method_name`) method of the class object
|
| 859 |
+
except if loading from a DDUF checkpoint. In that case, transformers models and tokenizers have a specific loading
|
| 860 |
+
method that we need to use.
|
| 861 |
+
"""
|
| 862 |
+
if is_dduf:
|
| 863 |
+
if issubclass(class_obj, PreTrainedTokenizerBase):
|
| 864 |
+
return lambda *args, **kwargs: _load_tokenizer_from_dduf(class_obj, *args, **kwargs)
|
| 865 |
+
if issubclass(class_obj, PreTrainedModel):
|
| 866 |
+
return lambda *args, **kwargs: _load_transformers_model_from_dduf(class_obj, *args, **kwargs)
|
| 867 |
+
return getattr(class_obj, load_method_name)
|
| 868 |
+
|
| 869 |
+
|
| 870 |
+
def _fetch_class_library_tuple(module):
|
| 871 |
+
# import it here to avoid circular import
|
| 872 |
+
diffusers_module = importlib.import_module(__name__.split(".")[0])
|
| 873 |
+
pipelines = getattr(diffusers_module, "pipelines")
|
| 874 |
+
|
| 875 |
+
# register the config from the original module, not the dynamo compiled one
|
| 876 |
+
not_compiled_module = _unwrap_model(module)
|
| 877 |
+
library = not_compiled_module.__module__.split(".")[0]
|
| 878 |
+
|
| 879 |
+
# check if the module is a pipeline module
|
| 880 |
+
module_path_items = not_compiled_module.__module__.split(".")
|
| 881 |
+
pipeline_dir = module_path_items[-2] if len(module_path_items) > 2 else None
|
| 882 |
+
|
| 883 |
+
path = not_compiled_module.__module__.split(".")
|
| 884 |
+
is_pipeline_module = pipeline_dir in path and hasattr(pipelines, pipeline_dir)
|
| 885 |
+
|
| 886 |
+
# if library is not in LOADABLE_CLASSES, then it is a custom module.
|
| 887 |
+
# Or if it's a pipeline module, then the module is inside the pipeline
|
| 888 |
+
# folder so we set the library to module name.
|
| 889 |
+
if is_pipeline_module:
|
| 890 |
+
library = pipeline_dir
|
| 891 |
+
elif library not in LOADABLE_CLASSES:
|
| 892 |
+
library = not_compiled_module.__module__
|
| 893 |
+
|
| 894 |
+
# retrieve class_name
|
| 895 |
+
class_name = not_compiled_module.__class__.__name__
|
| 896 |
+
|
| 897 |
+
return (library, class_name)
|
| 898 |
+
|
| 899 |
+
|
| 900 |
+
def _identify_model_variants(folder: str, variant: str, config: dict) -> dict:
|
| 901 |
+
model_variants = {}
|
| 902 |
+
if variant is not None:
|
| 903 |
+
for sub_folder in os.listdir(folder):
|
| 904 |
+
folder_path = os.path.join(folder, sub_folder)
|
| 905 |
+
is_folder = os.path.isdir(folder_path) and sub_folder in config
|
| 906 |
+
variant_exists = is_folder and any(p.split(".")[1].startswith(variant) for p in os.listdir(folder_path))
|
| 907 |
+
if variant_exists:
|
| 908 |
+
model_variants[sub_folder] = variant
|
| 909 |
+
return model_variants
|
| 910 |
+
|
| 911 |
+
|
| 912 |
+
def _resolve_custom_pipeline_and_cls(folder, config, custom_pipeline):
|
| 913 |
+
custom_class_name = None
|
| 914 |
+
if os.path.isfile(os.path.join(folder, f"{custom_pipeline}.py")):
|
| 915 |
+
custom_pipeline = os.path.join(folder, f"{custom_pipeline}.py")
|
| 916 |
+
elif isinstance(config["_class_name"], (list, tuple)) and os.path.isfile(
|
| 917 |
+
os.path.join(folder, f"{config['_class_name'][0]}.py")
|
| 918 |
+
):
|
| 919 |
+
custom_pipeline = os.path.join(folder, f"{config['_class_name'][0]}.py")
|
| 920 |
+
custom_class_name = config["_class_name"][1]
|
| 921 |
+
|
| 922 |
+
return custom_pipeline, custom_class_name
|
| 923 |
+
|
| 924 |
+
|
| 925 |
+
def _maybe_raise_warning_for_inpainting(pipeline_class, pretrained_model_name_or_path: str, config: dict):
|
| 926 |
+
if pipeline_class.__name__ == "StableDiffusionInpaintPipeline" and version.parse(
|
| 927 |
+
version.parse(config["_diffusers_version"]).base_version
|
| 928 |
+
) <= version.parse("0.5.1"):
|
| 929 |
+
from diffusers import StableDiffusionInpaintPipeline, StableDiffusionInpaintPipelineLegacy
|
| 930 |
+
|
| 931 |
+
pipeline_class = StableDiffusionInpaintPipelineLegacy
|
| 932 |
+
|
| 933 |
+
deprecation_message = (
|
| 934 |
+
"You are using a legacy checkpoint for inpainting with Stable Diffusion, therefore we are loading the"
|
| 935 |
+
f" {StableDiffusionInpaintPipelineLegacy} class instead of {StableDiffusionInpaintPipeline}. For"
|
| 936 |
+
" better inpainting results, we strongly suggest using Stable Diffusion's official inpainting"
|
| 937 |
+
" checkpoint: https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-inpainting instead or adapting your"
|
| 938 |
+
f" checkpoint {pretrained_model_name_or_path} to the format of"
|
| 939 |
+
" https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-inpainting. Note that we do not actively maintain"
|
| 940 |
+
" the {StableDiffusionInpaintPipelineLegacy} class and will likely remove it in version 1.0.0."
|
| 941 |
+
)
|
| 942 |
+
deprecate("StableDiffusionInpaintPipelineLegacy", "1.0.0", deprecation_message, standard_warn=False)
|
| 943 |
+
|
| 944 |
+
|
| 945 |
+
def _update_init_kwargs_with_connected_pipeline(
|
| 946 |
+
init_kwargs: dict, passed_pipe_kwargs: dict, passed_class_objs: dict, folder: str, **pipeline_loading_kwargs
|
| 947 |
+
) -> dict:
|
| 948 |
+
from .pipeline_utils import DiffusionPipeline
|
| 949 |
+
|
| 950 |
+
modelcard = ModelCard.load(os.path.join(folder, "README.md"))
|
| 951 |
+
connected_pipes = {prefix: getattr(modelcard.data, prefix, [None])[0] for prefix in CONNECTED_PIPES_KEYS}
|
| 952 |
+
|
| 953 |
+
# We don't scheduler argument to match the existing logic:
|
| 954 |
+
# https://github.com/huggingface/diffusers/blob/867e0c919e1aa7ef8b03c8eb1460f4f875a683ae/src/diffusers/pipelines/pipeline_utils.py#L906C13-L925C14
|
| 955 |
+
pipeline_loading_kwargs_cp = pipeline_loading_kwargs.copy()
|
| 956 |
+
if pipeline_loading_kwargs_cp is not None and len(pipeline_loading_kwargs_cp) >= 1:
|
| 957 |
+
for k in pipeline_loading_kwargs:
|
| 958 |
+
if "scheduler" in k:
|
| 959 |
+
_ = pipeline_loading_kwargs_cp.pop(k)
|
| 960 |
+
|
| 961 |
+
def get_connected_passed_kwargs(prefix):
|
| 962 |
+
connected_passed_class_obj = {
|
| 963 |
+
k.replace(f"{prefix}_", ""): w for k, w in passed_class_objs.items() if k.split("_")[0] == prefix
|
| 964 |
+
}
|
| 965 |
+
connected_passed_pipe_kwargs = {
|
| 966 |
+
k.replace(f"{prefix}_", ""): w for k, w in passed_pipe_kwargs.items() if k.split("_")[0] == prefix
|
| 967 |
+
}
|
| 968 |
+
|
| 969 |
+
connected_passed_kwargs = {**connected_passed_class_obj, **connected_passed_pipe_kwargs}
|
| 970 |
+
return connected_passed_kwargs
|
| 971 |
+
|
| 972 |
+
connected_pipes = {
|
| 973 |
+
prefix: DiffusionPipeline.from_pretrained(
|
| 974 |
+
repo_id, **pipeline_loading_kwargs_cp, **get_connected_passed_kwargs(prefix)
|
| 975 |
+
)
|
| 976 |
+
for prefix, repo_id in connected_pipes.items()
|
| 977 |
+
if repo_id is not None
|
| 978 |
+
}
|
| 979 |
+
|
| 980 |
+
for prefix, connected_pipe in connected_pipes.items():
|
| 981 |
+
# add connected pipes to `init_kwargs` with <prefix>_<component_name>, e.g. "prior_text_encoder"
|
| 982 |
+
init_kwargs.update(
|
| 983 |
+
{"_".join([prefix, name]): component for name, component in connected_pipe.components.items()}
|
| 984 |
+
)
|
| 985 |
+
|
| 986 |
+
return init_kwargs
|
| 987 |
+
|
| 988 |
+
|
| 989 |
+
def _get_custom_components_and_folders(
|
| 990 |
+
pretrained_model_name: str,
|
| 991 |
+
config_dict: Dict[str, Any],
|
| 992 |
+
filenames: Optional[List[str]] = None,
|
| 993 |
+
variant_filenames: Optional[List[str]] = None,
|
| 994 |
+
variant: Optional[str] = None,
|
| 995 |
+
):
|
| 996 |
+
config_dict = config_dict.copy()
|
| 997 |
+
|
| 998 |
+
# retrieve all folder_names that contain relevant files
|
| 999 |
+
folder_names = [k for k, v in config_dict.items() if isinstance(v, list) and k != "_class_name"]
|
| 1000 |
+
|
| 1001 |
+
diffusers_module = importlib.import_module(__name__.split(".")[0])
|
| 1002 |
+
pipelines = getattr(diffusers_module, "pipelines")
|
| 1003 |
+
|
| 1004 |
+
# optionally create a custom component <> custom file mapping
|
| 1005 |
+
custom_components = {}
|
| 1006 |
+
for component in folder_names:
|
| 1007 |
+
module_candidate = config_dict[component][0]
|
| 1008 |
+
|
| 1009 |
+
if module_candidate is None or not isinstance(module_candidate, str):
|
| 1010 |
+
continue
|
| 1011 |
+
|
| 1012 |
+
# We compute candidate file path on the Hub. Do not use `os.path.join`.
|
| 1013 |
+
candidate_file = f"{component}/{module_candidate}.py"
|
| 1014 |
+
|
| 1015 |
+
if candidate_file in filenames:
|
| 1016 |
+
custom_components[component] = module_candidate
|
| 1017 |
+
elif module_candidate not in LOADABLE_CLASSES and not hasattr(pipelines, module_candidate):
|
| 1018 |
+
raise ValueError(
|
| 1019 |
+
f"{candidate_file} as defined in `model_index.json` does not exist in {pretrained_model_name} and is not a module in 'diffusers/pipelines'."
|
| 1020 |
+
)
|
| 1021 |
+
|
| 1022 |
+
return custom_components, folder_names
|
| 1023 |
+
|
| 1024 |
+
|
| 1025 |
+
def _get_ignore_patterns(
|
| 1026 |
+
passed_components,
|
| 1027 |
+
model_folder_names: List[str],
|
| 1028 |
+
model_filenames: List[str],
|
| 1029 |
+
use_safetensors: bool,
|
| 1030 |
+
from_flax: bool,
|
| 1031 |
+
allow_pickle: bool,
|
| 1032 |
+
use_onnx: bool,
|
| 1033 |
+
is_onnx: bool,
|
| 1034 |
+
variant: Optional[str] = None,
|
| 1035 |
+
) -> List[str]:
|
| 1036 |
+
if (
|
| 1037 |
+
use_safetensors
|
| 1038 |
+
and not allow_pickle
|
| 1039 |
+
and not is_safetensors_compatible(
|
| 1040 |
+
model_filenames, passed_components=passed_components, folder_names=model_folder_names, variant=variant
|
| 1041 |
+
)
|
| 1042 |
+
):
|
| 1043 |
+
raise EnvironmentError(
|
| 1044 |
+
f"Could not find the necessary `safetensors` weights in {model_filenames} (variant={variant})"
|
| 1045 |
+
)
|
| 1046 |
+
|
| 1047 |
+
if from_flax:
|
| 1048 |
+
ignore_patterns = ["*.bin", "*.safetensors", "*.onnx", "*.pb"]
|
| 1049 |
+
|
| 1050 |
+
elif use_safetensors and is_safetensors_compatible(
|
| 1051 |
+
model_filenames, passed_components=passed_components, folder_names=model_folder_names, variant=variant
|
| 1052 |
+
):
|
| 1053 |
+
ignore_patterns = ["*.bin", "*.msgpack"]
|
| 1054 |
+
|
| 1055 |
+
use_onnx = use_onnx if use_onnx is not None else is_onnx
|
| 1056 |
+
if not use_onnx:
|
| 1057 |
+
ignore_patterns += ["*.onnx", "*.pb"]
|
| 1058 |
+
|
| 1059 |
+
else:
|
| 1060 |
+
ignore_patterns = ["*.safetensors", "*.msgpack"]
|
| 1061 |
+
|
| 1062 |
+
use_onnx = use_onnx if use_onnx is not None else is_onnx
|
| 1063 |
+
if not use_onnx:
|
| 1064 |
+
ignore_patterns += ["*.onnx", "*.pb"]
|
| 1065 |
+
|
| 1066 |
+
return ignore_patterns
|
| 1067 |
+
|
| 1068 |
+
|
| 1069 |
+
def _download_dduf_file(
|
| 1070 |
+
pretrained_model_name: str,
|
| 1071 |
+
dduf_file: str,
|
| 1072 |
+
pipeline_class_name: str,
|
| 1073 |
+
cache_dir: str,
|
| 1074 |
+
proxies: str,
|
| 1075 |
+
local_files_only: bool,
|
| 1076 |
+
token: str,
|
| 1077 |
+
revision: str,
|
| 1078 |
+
):
|
| 1079 |
+
model_info_call_error = None
|
| 1080 |
+
if not local_files_only:
|
| 1081 |
+
try:
|
| 1082 |
+
info = model_info(pretrained_model_name, token=token, revision=revision)
|
| 1083 |
+
except (HTTPError, OfflineModeIsEnabled, requests.ConnectionError) as e:
|
| 1084 |
+
logger.warning(f"Couldn't connect to the Hub: {e}.\nWill try to load from local cache.")
|
| 1085 |
+
local_files_only = True
|
| 1086 |
+
model_info_call_error = e # save error to reraise it if model is not cached locally
|
| 1087 |
+
|
| 1088 |
+
if (
|
| 1089 |
+
not local_files_only
|
| 1090 |
+
and dduf_file is not None
|
| 1091 |
+
and dduf_file not in (sibling.rfilename for sibling in info.siblings)
|
| 1092 |
+
):
|
| 1093 |
+
raise ValueError(f"Requested {dduf_file} file is not available in {pretrained_model_name}.")
|
| 1094 |
+
|
| 1095 |
+
try:
|
| 1096 |
+
user_agent = {"pipeline_class": pipeline_class_name, "dduf": True}
|
| 1097 |
+
cached_folder = snapshot_download(
|
| 1098 |
+
pretrained_model_name,
|
| 1099 |
+
cache_dir=cache_dir,
|
| 1100 |
+
proxies=proxies,
|
| 1101 |
+
local_files_only=local_files_only,
|
| 1102 |
+
token=token,
|
| 1103 |
+
revision=revision,
|
| 1104 |
+
allow_patterns=[dduf_file],
|
| 1105 |
+
user_agent=user_agent,
|
| 1106 |
+
)
|
| 1107 |
+
return cached_folder
|
| 1108 |
+
except FileNotFoundError:
|
| 1109 |
+
# Means we tried to load pipeline with `local_files_only=True` but the files have not been found in local cache.
|
| 1110 |
+
# This can happen in two cases:
|
| 1111 |
+
# 1. If the user passed `local_files_only=True` => we raise the error directly
|
| 1112 |
+
# 2. If we forced `local_files_only=True` when `model_info` failed => we raise the initial error
|
| 1113 |
+
if model_info_call_error is None:
|
| 1114 |
+
# 1. user passed `local_files_only=True`
|
| 1115 |
+
raise
|
| 1116 |
+
else:
|
| 1117 |
+
# 2. we forced `local_files_only=True` when `model_info` failed
|
| 1118 |
+
raise EnvironmentError(
|
| 1119 |
+
f"Cannot load model {pretrained_model_name}: model is not cached locally and an error occurred"
|
| 1120 |
+
" while trying to fetch metadata from the Hub. Please check out the root cause in the stacktrace"
|
| 1121 |
+
" above."
|
| 1122 |
+
) from model_info_call_error
|
| 1123 |
+
|
| 1124 |
+
|
| 1125 |
+
def _maybe_raise_error_for_incorrect_transformers(config_dict):
|
| 1126 |
+
has_transformers_component = False
|
| 1127 |
+
for k in config_dict:
|
| 1128 |
+
if isinstance(config_dict[k], list):
|
| 1129 |
+
has_transformers_component = config_dict[k][0] == "transformers"
|
| 1130 |
+
if has_transformers_component:
|
| 1131 |
+
break
|
| 1132 |
+
if has_transformers_component and not is_transformers_version(">", "4.47.1"):
|
| 1133 |
+
raise ValueError("Please upgrade your `transformers` installation to the latest version to use DDUF.")
|
| 1134 |
+
|
| 1135 |
+
|
| 1136 |
+
def _maybe_warn_for_wrong_component_in_quant_config(pipe_init_dict, quant_config):
|
| 1137 |
+
if quant_config is None:
|
| 1138 |
+
return
|
| 1139 |
+
|
| 1140 |
+
actual_pipe_components = set(pipe_init_dict.keys())
|
| 1141 |
+
missing = ""
|
| 1142 |
+
quant_components = None
|
| 1143 |
+
if getattr(quant_config, "components_to_quantize", None) is not None:
|
| 1144 |
+
quant_components = set(quant_config.components_to_quantize)
|
| 1145 |
+
elif getattr(quant_config, "quant_mapping", None) is not None and isinstance(quant_config.quant_mapping, dict):
|
| 1146 |
+
quant_components = set(quant_config.quant_mapping.keys())
|
| 1147 |
+
|
| 1148 |
+
if quant_components and not quant_components.issubset(actual_pipe_components):
|
| 1149 |
+
missing = quant_components - actual_pipe_components
|
| 1150 |
+
|
| 1151 |
+
if missing:
|
| 1152 |
+
logger.warning(
|
| 1153 |
+
f"The following components in the quantization config {missing} will be ignored "
|
| 1154 |
+
"as they do not belong to the underlying pipeline. Acceptable values for the pipeline "
|
| 1155 |
+
f"components are: {', '.join(actual_pipe_components)}."
|
| 1156 |
+
)
|
venv/lib/python3.10/site-packages/diffusers/pipelines/pipeline_utils.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
venv/lib/python3.10/site-packages/diffusers/pipelines/stable_diffusion/__init__.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import TYPE_CHECKING
|
| 2 |
+
|
| 3 |
+
from ...utils import (
|
| 4 |
+
DIFFUSERS_SLOW_IMPORT,
|
| 5 |
+
OptionalDependencyNotAvailable,
|
| 6 |
+
_LazyModule,
|
| 7 |
+
get_objects_from_module,
|
| 8 |
+
is_flax_available,
|
| 9 |
+
is_k_diffusion_available,
|
| 10 |
+
is_k_diffusion_version,
|
| 11 |
+
is_onnx_available,
|
| 12 |
+
is_torch_available,
|
| 13 |
+
is_transformers_available,
|
| 14 |
+
is_transformers_version,
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
_dummy_objects = {}
|
| 19 |
+
_additional_imports = {}
|
| 20 |
+
_import_structure = {"pipeline_output": ["StableDiffusionPipelineOutput"]}
|
| 21 |
+
|
| 22 |
+
if is_transformers_available() and is_flax_available():
|
| 23 |
+
_import_structure["pipeline_output"].extend(["FlaxStableDiffusionPipelineOutput"])
|
| 24 |
+
try:
|
| 25 |
+
if not (is_transformers_available() and is_torch_available()):
|
| 26 |
+
raise OptionalDependencyNotAvailable()
|
| 27 |
+
except OptionalDependencyNotAvailable:
|
| 28 |
+
from ...utils import dummy_torch_and_transformers_objects # noqa F403
|
| 29 |
+
|
| 30 |
+
_dummy_objects.update(get_objects_from_module(dummy_torch_and_transformers_objects))
|
| 31 |
+
else:
|
| 32 |
+
_import_structure["clip_image_project_model"] = ["CLIPImageProjection"]
|
| 33 |
+
_import_structure["pipeline_stable_diffusion"] = ["StableDiffusionPipeline"]
|
| 34 |
+
_import_structure["pipeline_stable_diffusion_img2img"] = ["StableDiffusionImg2ImgPipeline"]
|
| 35 |
+
_import_structure["pipeline_stable_diffusion_inpaint"] = ["StableDiffusionInpaintPipeline"]
|
| 36 |
+
_import_structure["pipeline_stable_diffusion_instruct_pix2pix"] = ["StableDiffusionInstructPix2PixPipeline"]
|
| 37 |
+
_import_structure["pipeline_stable_diffusion_latent_upscale"] = ["StableDiffusionLatentUpscalePipeline"]
|
| 38 |
+
_import_structure["pipeline_stable_diffusion_upscale"] = ["StableDiffusionUpscalePipeline"]
|
| 39 |
+
_import_structure["pipeline_stable_unclip"] = ["StableUnCLIPPipeline"]
|
| 40 |
+
_import_structure["pipeline_stable_unclip_img2img"] = ["StableUnCLIPImg2ImgPipeline"]
|
| 41 |
+
_import_structure["safety_checker"] = ["StableDiffusionSafetyChecker"]
|
| 42 |
+
_import_structure["stable_unclip_image_normalizer"] = ["StableUnCLIPImageNormalizer"]
|
| 43 |
+
try:
|
| 44 |
+
if not (is_transformers_available() and is_torch_available() and is_transformers_version(">=", "4.25.0")):
|
| 45 |
+
raise OptionalDependencyNotAvailable()
|
| 46 |
+
except OptionalDependencyNotAvailable:
|
| 47 |
+
from ...utils.dummy_torch_and_transformers_objects import (
|
| 48 |
+
StableDiffusionImageVariationPipeline,
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
_dummy_objects.update({"StableDiffusionImageVariationPipeline": StableDiffusionImageVariationPipeline})
|
| 52 |
+
else:
|
| 53 |
+
_import_structure["pipeline_stable_diffusion_image_variation"] = ["StableDiffusionImageVariationPipeline"]
|
| 54 |
+
try:
|
| 55 |
+
if not (is_transformers_available() and is_torch_available() and is_transformers_version(">=", "4.26.0")):
|
| 56 |
+
raise OptionalDependencyNotAvailable()
|
| 57 |
+
except OptionalDependencyNotAvailable:
|
| 58 |
+
from ...utils.dummy_torch_and_transformers_objects import (
|
| 59 |
+
StableDiffusionDepth2ImgPipeline,
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
_dummy_objects.update(
|
| 63 |
+
{
|
| 64 |
+
"StableDiffusionDepth2ImgPipeline": StableDiffusionDepth2ImgPipeline,
|
| 65 |
+
}
|
| 66 |
+
)
|
| 67 |
+
else:
|
| 68 |
+
_import_structure["pipeline_stable_diffusion_depth2img"] = ["StableDiffusionDepth2ImgPipeline"]
|
| 69 |
+
|
| 70 |
+
try:
|
| 71 |
+
if not (is_transformers_available() and is_onnx_available()):
|
| 72 |
+
raise OptionalDependencyNotAvailable()
|
| 73 |
+
except OptionalDependencyNotAvailable:
|
| 74 |
+
from ...utils import dummy_onnx_objects # noqa F403
|
| 75 |
+
|
| 76 |
+
_dummy_objects.update(get_objects_from_module(dummy_onnx_objects))
|
| 77 |
+
else:
|
| 78 |
+
_import_structure["pipeline_onnx_stable_diffusion"] = [
|
| 79 |
+
"OnnxStableDiffusionPipeline",
|
| 80 |
+
"StableDiffusionOnnxPipeline",
|
| 81 |
+
]
|
| 82 |
+
_import_structure["pipeline_onnx_stable_diffusion_img2img"] = ["OnnxStableDiffusionImg2ImgPipeline"]
|
| 83 |
+
_import_structure["pipeline_onnx_stable_diffusion_inpaint"] = ["OnnxStableDiffusionInpaintPipeline"]
|
| 84 |
+
_import_structure["pipeline_onnx_stable_diffusion_inpaint_legacy"] = ["OnnxStableDiffusionInpaintPipelineLegacy"]
|
| 85 |
+
_import_structure["pipeline_onnx_stable_diffusion_upscale"] = ["OnnxStableDiffusionUpscalePipeline"]
|
| 86 |
+
|
| 87 |
+
if is_transformers_available() and is_flax_available():
|
| 88 |
+
from ...schedulers.scheduling_pndm_flax import PNDMSchedulerState
|
| 89 |
+
|
| 90 |
+
_additional_imports.update({"PNDMSchedulerState": PNDMSchedulerState})
|
| 91 |
+
_import_structure["pipeline_flax_stable_diffusion"] = ["FlaxStableDiffusionPipeline"]
|
| 92 |
+
_import_structure["pipeline_flax_stable_diffusion_img2img"] = ["FlaxStableDiffusionImg2ImgPipeline"]
|
| 93 |
+
_import_structure["pipeline_flax_stable_diffusion_inpaint"] = ["FlaxStableDiffusionInpaintPipeline"]
|
| 94 |
+
_import_structure["safety_checker_flax"] = ["FlaxStableDiffusionSafetyChecker"]
|
| 95 |
+
|
| 96 |
+
if TYPE_CHECKING or DIFFUSERS_SLOW_IMPORT:
|
| 97 |
+
try:
|
| 98 |
+
if not (is_transformers_available() and is_torch_available()):
|
| 99 |
+
raise OptionalDependencyNotAvailable()
|
| 100 |
+
|
| 101 |
+
except OptionalDependencyNotAvailable:
|
| 102 |
+
from ...utils.dummy_torch_and_transformers_objects import *
|
| 103 |
+
|
| 104 |
+
else:
|
| 105 |
+
from .clip_image_project_model import CLIPImageProjection
|
| 106 |
+
from .pipeline_stable_diffusion import (
|
| 107 |
+
StableDiffusionPipeline,
|
| 108 |
+
StableDiffusionPipelineOutput,
|
| 109 |
+
)
|
| 110 |
+
from .pipeline_stable_diffusion_img2img import StableDiffusionImg2ImgPipeline
|
| 111 |
+
from .pipeline_stable_diffusion_inpaint import StableDiffusionInpaintPipeline
|
| 112 |
+
from .pipeline_stable_diffusion_instruct_pix2pix import (
|
| 113 |
+
StableDiffusionInstructPix2PixPipeline,
|
| 114 |
+
)
|
| 115 |
+
from .pipeline_stable_diffusion_latent_upscale import (
|
| 116 |
+
StableDiffusionLatentUpscalePipeline,
|
| 117 |
+
)
|
| 118 |
+
from .pipeline_stable_diffusion_upscale import StableDiffusionUpscalePipeline
|
| 119 |
+
from .pipeline_stable_unclip import StableUnCLIPPipeline
|
| 120 |
+
from .pipeline_stable_unclip_img2img import StableUnCLIPImg2ImgPipeline
|
| 121 |
+
from .safety_checker import StableDiffusionSafetyChecker
|
| 122 |
+
from .stable_unclip_image_normalizer import StableUnCLIPImageNormalizer
|
| 123 |
+
|
| 124 |
+
try:
|
| 125 |
+
if not (is_transformers_available() and is_torch_available() and is_transformers_version(">=", "4.25.0")):
|
| 126 |
+
raise OptionalDependencyNotAvailable()
|
| 127 |
+
except OptionalDependencyNotAvailable:
|
| 128 |
+
from ...utils.dummy_torch_and_transformers_objects import (
|
| 129 |
+
StableDiffusionImageVariationPipeline,
|
| 130 |
+
)
|
| 131 |
+
else:
|
| 132 |
+
from .pipeline_stable_diffusion_image_variation import (
|
| 133 |
+
StableDiffusionImageVariationPipeline,
|
| 134 |
+
)
|
| 135 |
+
|
| 136 |
+
try:
|
| 137 |
+
if not (is_transformers_available() and is_torch_available() and is_transformers_version(">=", "4.26.0")):
|
| 138 |
+
raise OptionalDependencyNotAvailable()
|
| 139 |
+
except OptionalDependencyNotAvailable:
|
| 140 |
+
from ...utils.dummy_torch_and_transformers_objects import StableDiffusionDepth2ImgPipeline
|
| 141 |
+
else:
|
| 142 |
+
from .pipeline_stable_diffusion_depth2img import (
|
| 143 |
+
StableDiffusionDepth2ImgPipeline,
|
| 144 |
+
)
|
| 145 |
+
|
| 146 |
+
try:
|
| 147 |
+
if not (is_transformers_available() and is_onnx_available()):
|
| 148 |
+
raise OptionalDependencyNotAvailable()
|
| 149 |
+
except OptionalDependencyNotAvailable:
|
| 150 |
+
from ...utils.dummy_onnx_objects import *
|
| 151 |
+
else:
|
| 152 |
+
from .pipeline_onnx_stable_diffusion import (
|
| 153 |
+
OnnxStableDiffusionPipeline,
|
| 154 |
+
StableDiffusionOnnxPipeline,
|
| 155 |
+
)
|
| 156 |
+
from .pipeline_onnx_stable_diffusion_img2img import (
|
| 157 |
+
OnnxStableDiffusionImg2ImgPipeline,
|
| 158 |
+
)
|
| 159 |
+
from .pipeline_onnx_stable_diffusion_inpaint import (
|
| 160 |
+
OnnxStableDiffusionInpaintPipeline,
|
| 161 |
+
)
|
| 162 |
+
from .pipeline_onnx_stable_diffusion_upscale import (
|
| 163 |
+
OnnxStableDiffusionUpscalePipeline,
|
| 164 |
+
)
|
| 165 |
+
|
| 166 |
+
try:
|
| 167 |
+
if not (is_transformers_available() and is_flax_available()):
|
| 168 |
+
raise OptionalDependencyNotAvailable()
|
| 169 |
+
except OptionalDependencyNotAvailable:
|
| 170 |
+
from ...utils.dummy_flax_objects import *
|
| 171 |
+
else:
|
| 172 |
+
from .pipeline_flax_stable_diffusion import FlaxStableDiffusionPipeline
|
| 173 |
+
from .pipeline_flax_stable_diffusion_img2img import (
|
| 174 |
+
FlaxStableDiffusionImg2ImgPipeline,
|
| 175 |
+
)
|
| 176 |
+
from .pipeline_flax_stable_diffusion_inpaint import (
|
| 177 |
+
FlaxStableDiffusionInpaintPipeline,
|
| 178 |
+
)
|
| 179 |
+
from .pipeline_output import FlaxStableDiffusionPipelineOutput
|
| 180 |
+
from .safety_checker_flax import FlaxStableDiffusionSafetyChecker
|
| 181 |
+
|
| 182 |
+
else:
|
| 183 |
+
import sys
|
| 184 |
+
|
| 185 |
+
sys.modules[__name__] = _LazyModule(
|
| 186 |
+
__name__,
|
| 187 |
+
globals()["__file__"],
|
| 188 |
+
_import_structure,
|
| 189 |
+
module_spec=__spec__,
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
for name, value in _dummy_objects.items():
|
| 193 |
+
setattr(sys.modules[__name__], name, value)
|
| 194 |
+
for name, value in _additional_imports.items():
|
| 195 |
+
setattr(sys.modules[__name__], name, value)
|