diff --git a/docker/diffusers-flax-cpu/Dockerfile b/docker/diffusers-flax-cpu/Dockerfile index cd65c465..57a9c1ec 100644 --- a/docker/diffusers-flax-cpu/Dockerfile +++ b/docker/diffusers-flax-cpu/Dockerfile @@ -34,8 +34,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/docker/diffusers-flax-tpu/Dockerfile b/docker/diffusers-flax-tpu/Dockerfile index f68ba8b5..2517da58 100644 --- a/docker/diffusers-flax-tpu/Dockerfile +++ b/docker/diffusers-flax-tpu/Dockerfile @@ -36,8 +36,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/docker/diffusers-onnxruntime-cpu/Dockerfile b/docker/diffusers-onnxruntime-cpu/Dockerfile index e3ae56f8..75f45be8 100644 --- a/docker/diffusers-onnxruntime-cpu/Dockerfile +++ b/docker/diffusers-onnxruntime-cpu/Dockerfile @@ -34,8 +34,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/docker/diffusers-onnxruntime-cuda/Dockerfile b/docker/diffusers-onnxruntime-cuda/Dockerfile index c3d2ff7a..2129dbca 100644 --- a/docker/diffusers-onnxruntime-cuda/Dockerfile +++ b/docker/diffusers-onnxruntime-cuda/Dockerfile @@ -34,8 +34,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/docker/diffusers-pytorch-cpu/Dockerfile b/docker/diffusers-pytorch-cpu/Dockerfile index 2c7bf17d..a70eff4c 100644 --- a/docker/diffusers-pytorch-cpu/Dockerfile +++ b/docker/diffusers-pytorch-cpu/Dockerfile @@ -33,8 +33,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/docker/diffusers-pytorch-cuda/Dockerfile b/docker/diffusers-pytorch-cuda/Dockerfile index ac974507..1c5ac399 100644 --- a/docker/diffusers-pytorch-cuda/Dockerfile +++ b/docker/diffusers-pytorch-cuda/Dockerfile @@ -33,8 +33,8 @@ RUN python3 -m pip install --no-cache-dir --upgrade pip && \ datasets \ hf-doc-builder \ huggingface-hub \ + Jinja2 \ librosa \ - modelcards \ numpy \ scipy \ tensorboard \ diff --git a/examples/dreambooth/requirements.txt b/examples/dreambooth/requirements.txt index 3a1731c2..7d93f3d0 100644 --- a/examples/dreambooth/requirements.txt +++ b/examples/dreambooth/requirements.txt @@ -3,4 +3,4 @@ torchvision transformers>=4.25.1 ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/dreambooth/requirements_flax.txt b/examples/dreambooth/requirements_flax.txt index ca459cd7..8f85ad52 100644 --- a/examples/dreambooth/requirements_flax.txt +++ b/examples/dreambooth/requirements_flax.txt @@ -5,4 +5,4 @@ torch torchvision ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/research_projects/colossalai/requirement.txt b/examples/research_projects/colossalai/requirement.txt index 9723a30d..f80467dc 100644 --- a/examples/research_projects/colossalai/requirement.txt +++ b/examples/research_projects/colossalai/requirement.txt @@ -3,5 +3,5 @@ torch torchvision ftfy tensorboard -modelcards +Jinja2 transformers \ No newline at end of file diff --git a/examples/research_projects/dreambooth_inpaint/requirements.txt b/examples/research_projects/dreambooth_inpaint/requirements.txt index 60639311..f17dfab9 100644 --- a/examples/research_projects/dreambooth_inpaint/requirements.txt +++ b/examples/research_projects/dreambooth_inpaint/requirements.txt @@ -4,4 +4,4 @@ torchvision transformers>=4.21.0 ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/research_projects/intel_opts/textual_inversion/requirements.txt b/examples/research_projects/intel_opts/textual_inversion/requirements.txt index 7e2874c7..17b32ea8 100644 --- a/examples/research_projects/intel_opts/textual_inversion/requirements.txt +++ b/examples/research_projects/intel_opts/textual_inversion/requirements.txt @@ -3,5 +3,5 @@ torchvision transformers>=4.21.0 ftfy tensorboard -modelcards +Jinja2 intel_extension_for_pytorch>=1.13 diff --git a/examples/research_projects/multi_subject_dreambooth/requirements.txt b/examples/research_projects/multi_subject_dreambooth/requirements.txt index cde1e75c..bbf6c5be 100644 --- a/examples/research_projects/multi_subject_dreambooth/requirements.txt +++ b/examples/research_projects/multi_subject_dreambooth/requirements.txt @@ -3,4 +3,4 @@ torchvision transformers>=4.25.1 ftfy tensorboard -modelcards \ No newline at end of file +Jinja2 \ No newline at end of file diff --git a/examples/text_to_image/requirements.txt b/examples/text_to_image/requirements.txt index b597d546..a71be671 100644 --- a/examples/text_to_image/requirements.txt +++ b/examples/text_to_image/requirements.txt @@ -4,4 +4,4 @@ transformers>=4.25.1 datasets ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/text_to_image/requirements_flax.txt b/examples/text_to_image/requirements_flax.txt index d32b7cd4..b6eb64e2 100644 --- a/examples/text_to_image/requirements_flax.txt +++ b/examples/text_to_image/requirements_flax.txt @@ -6,4 +6,4 @@ torch torchvision ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/textual_inversion/requirements.txt b/examples/textual_inversion/requirements.txt index 3a1731c2..7d93f3d0 100644 --- a/examples/textual_inversion/requirements.txt +++ b/examples/textual_inversion/requirements.txt @@ -3,4 +3,4 @@ torchvision transformers>=4.25.1 ftfy tensorboard -modelcards +Jinja2 diff --git a/examples/textual_inversion/requirements_flax.txt b/examples/textual_inversion/requirements_flax.txt index ca459cd7..8f85ad52 100644 --- a/examples/textual_inversion/requirements_flax.txt +++ b/examples/textual_inversion/requirements_flax.txt @@ -5,4 +5,4 @@ torch torchvision ftfy tensorboard -modelcards +Jinja2 diff --git a/setup.py b/setup.py index 0a6078fe..5c4aaa65 100644 --- a/setup.py +++ b/setup.py @@ -91,9 +91,9 @@ _deps = [ "isort>=5.5.4", "jax>=0.2.8,!=0.3.2", "jaxlib>=0.1.65", + "Jinja2", "k-diffusion>=0.0.12", "librosa", - "modelcards>=0.1.4", "numpy", "parameterized", "pytest", @@ -180,9 +180,10 @@ extras = {} extras = {} extras["quality"] = deps_list("black", "isort", "flake8", "hf-doc-builder") extras["docs"] = deps_list("hf-doc-builder") -extras["training"] = deps_list("accelerate", "datasets", "tensorboard", "modelcards") +extras["training"] = deps_list("accelerate", "datasets", "tensorboard", "Jinja2") extras["test"] = deps_list( "datasets", + "Jinja2", "k-diffusion", "librosa", "parameterized", diff --git a/src/diffusers/dependency_versions_table.py b/src/diffusers/dependency_versions_table.py index a995c207..2fb6959e 100644 --- a/src/diffusers/dependency_versions_table.py +++ b/src/diffusers/dependency_versions_table.py @@ -15,9 +15,9 @@ deps = { "isort": "isort>=5.5.4", "jax": "jax>=0.2.8,!=0.3.2", "jaxlib": "jaxlib>=0.1.65", + "Jinja2": "Jinja2", "k-diffusion": "k-diffusion>=0.0.12", "librosa": "librosa", - "modelcards": "modelcards>=0.1.4", "numpy": "numpy", "parameterized": "parameterized", "pytest": "pytest", diff --git a/src/diffusers/utils/__init__.py b/src/diffusers/utils/__init__.py index c2c6a765..3355b6da 100644 --- a/src/diffusers/utils/__init__.py +++ b/src/diffusers/utils/__init__.py @@ -48,7 +48,6 @@ from .import_utils import ( is_k_diffusion_available, is_k_diffusion_version, is_librosa_available, - is_modelcards_available, is_onnx_available, is_safetensors_available, is_scipy_available, diff --git a/src/diffusers/utils/hub_utils.py b/src/diffusers/utils/hub_utils.py index e22b3644..ea00058f 100644 --- a/src/diffusers/utils/hub_utils.py +++ b/src/diffusers/utils/hub_utils.py @@ -20,7 +20,8 @@ from pathlib import Path from typing import Dict, Optional, Union from uuid import uuid4 -from huggingface_hub import HfFolder, whoami +from huggingface_hub import HfFolder, ModelCard, ModelCardData, whoami +from huggingface_hub.utils import is_jinja_available from .. import __version__ from .constants import HUGGINGFACE_CO_RESOLVE_ENDPOINT @@ -31,21 +32,16 @@ from .import_utils import ( _onnxruntime_version, _torch_version, is_flax_available, - is_modelcards_available, is_onnx_available, is_torch_available, ) from .logging import get_logger -if is_modelcards_available(): - from modelcards import CardData, ModelCard - - logger = get_logger(__name__) -MODEL_CARD_TEMPLATE_PATH = Path(__file__).parent / "utils" / "model_card_template.md" +MODEL_CARD_TEMPLATE_PATH = Path(__file__).parent / "model_card_template.md" SESSION_ID = uuid4().hex HF_HUB_OFFLINE = os.getenv("HF_HUB_OFFLINE", "").upper() in ENV_VARS_TRUE_VALUES DISABLE_TELEMETRY = os.getenv("DISABLE_TELEMETRY", "").upper() in ENV_VARS_TRUE_VALUES @@ -87,10 +83,11 @@ def get_full_repo_name(model_id: str, organization: Optional[str] = None, token: def create_model_card(args, model_name): - if not is_modelcards_available: + if not is_jinja_available(): raise ValueError( - "Please make sure to have `modelcards` installed when using the `create_model_card` function. You can" - " install the package with `pip install modelcards`." + "Modelcard rendering is based on Jinja templates." + " Please make sure to have `jinja` installed before using `create_model_card`." + " To install it, please run `pip install Jinja2`." ) if hasattr(args, "local_rank") and args.local_rank not in [-1, 0]: @@ -100,7 +97,7 @@ def create_model_card(args, model_name): repo_name = get_full_repo_name(model_name, token=hub_token) model_card = ModelCard.from_template( - card_data=CardData( # Card metadata object that will be converted to YAML block + card_data=ModelCardData( # Card metadata object that will be converted to YAML block language="en", license="apache-2.0", library_name="diffusers", diff --git a/src/diffusers/utils/import_utils.py b/src/diffusers/utils/import_utils.py index d99cf974..166c9728 100644 --- a/src/diffusers/utils/import_utils.py +++ b/src/diffusers/utils/import_utils.py @@ -21,6 +21,7 @@ import sys from collections import OrderedDict from typing import Union +from huggingface_hub.utils import is_jinja_available # noqa: F401 from packaging import version from packaging.version import Version, parse @@ -146,14 +147,6 @@ except importlib_metadata.PackageNotFoundError: _unidecode_available = False -_modelcards_available = importlib.util.find_spec("modelcards") is not None -try: - _modelcards_version = importlib_metadata.version("modelcards") - logger.debug(f"Successfully imported modelcards version {_modelcards_version}") -except importlib_metadata.PackageNotFoundError: - _modelcards_available = False - - _onnxruntime_version = "N/A" _onnx_available = importlib.util.find_spec("onnxruntime") is not None if _onnx_available: @@ -253,10 +246,6 @@ def is_unidecode_available(): return _unidecode_available -def is_modelcards_available(): - return _modelcards_available - - def is_onnx_available(): return _onnx_available diff --git a/tests/test_hub_utils.py b/tests/test_hub_utils.py new file mode 100644 index 00000000..e8b8ea3a --- /dev/null +++ b/tests/test_hub_utils.py @@ -0,0 +1,51 @@ +# coding=utf-8 +# Copyright 2023 HuggingFace Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest +from pathlib import Path +from tempfile import TemporaryDirectory +from unittest.mock import Mock, patch + +import diffusers.utils.hub_utils + + +class CreateModelCardTest(unittest.TestCase): + @patch("diffusers.utils.hub_utils.get_full_repo_name") + def test_create_model_card(self, repo_name_mock: Mock) -> None: + repo_name_mock.return_value = "full_repo_name" + with TemporaryDirectory() as tmpdir: + # Dummy args values + args = Mock() + args.output_dir = tmpdir + args.local_rank = 0 + args.hub_token = "hub_token" + args.dataset_name = "dataset_name" + args.learning_rate = 0.01 + args.train_batch_size = 100000 + args.eval_batch_size = 10000 + args.gradient_accumulation_steps = 0.01 + args.adam_beta1 = 0.02 + args.adam_beta2 = 0.03 + args.adam_weight_decay = 0.0005 + args.adam_epsilon = 0.000001 + args.lr_scheduler = 1 + args.lr_warmup_steps = 10 + args.ema_inv_gamma = 0.001 + args.ema_power = 0.1 + args.ema_max_decay = 0.2 + args.mixed_precision = True + + # Model card mush be rendered and saved + diffusers.utils.hub_utils.create_model_card(args, model_name="model_name") + self.assertTrue((Path(tmpdir) / "README.md").is_file())