mirror of
https://github.com/huggingface/diffusers.git
synced 2026-10-23 09:09:01 +03:00
223 lines
6.7 KiB
Python
223 lines
6.7 KiB
Python
# coding=utf-8
|
|
# Copyright 2026 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 PIL.Image
|
|
import pytest
|
|
import torch
|
|
|
|
from diffusers.utils import load_image
|
|
from diffusers.utils.constants import (
|
|
DECODE_ENDPOINT_FLUX,
|
|
DECODE_ENDPOINT_SD_V1,
|
|
DECODE_ENDPOINT_SD_XL,
|
|
ENCODE_ENDPOINT_FLUX,
|
|
ENCODE_ENDPOINT_SD_V1,
|
|
ENCODE_ENDPOINT_SD_XL,
|
|
)
|
|
from diffusers.utils.remote_utils import (
|
|
remote_decode,
|
|
remote_encode,
|
|
)
|
|
|
|
from ..testing_utils import (
|
|
enable_full_determinism,
|
|
slow,
|
|
)
|
|
|
|
|
|
enable_full_determinism()
|
|
|
|
IMAGE = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg?download=true"
|
|
|
|
# The `ENCODE_ENDPOINT_*` Inference Endpoints these tests call have been undeployed and now answer every
|
|
# request with `404 NOT_FOUND`, which `remote_encode` surfaces as a `RuntimeError`. Nothing in the repo can
|
|
# bring them back, so the tests are marked `xfail` rather than deleted: if the endpoints are ever redeployed
|
|
# the suite reports XPASS and the marker can be dropped.
|
|
ENDPOINTS_GONE = pytest.mark.xfail(
|
|
reason="ENCODE_ENDPOINT_* are no longer deployed and return 404 NOT_FOUND.",
|
|
raises=RuntimeError,
|
|
)
|
|
|
|
|
|
class RemoteAutoencoderKLEncodeMixin:
|
|
channels: int = None
|
|
endpoint: str = None
|
|
decode_endpoint: str = None
|
|
dtype: torch.dtype = None
|
|
scaling_factor: float = None
|
|
shift_factor: float = None
|
|
image: PIL.Image.Image = None
|
|
|
|
def get_dummy_inputs(self):
|
|
if self.image is None:
|
|
self.image = load_image(IMAGE)
|
|
inputs = {
|
|
"endpoint": self.endpoint,
|
|
"image": self.image,
|
|
"scaling_factor": self.scaling_factor,
|
|
"shift_factor": self.shift_factor,
|
|
}
|
|
return inputs
|
|
|
|
@ENDPOINTS_GONE
|
|
def test_image_input(self):
|
|
inputs = self.get_dummy_inputs()
|
|
height, width = inputs["image"].height, inputs["image"].width
|
|
output = remote_encode(**inputs)
|
|
assert list(output.shape) == [1, self.channels, height // 8, width // 8]
|
|
decoded = remote_decode(
|
|
tensor=output,
|
|
endpoint=self.decode_endpoint,
|
|
scaling_factor=self.scaling_factor,
|
|
shift_factor=self.shift_factor,
|
|
image_format="png",
|
|
)
|
|
assert decoded.height == height
|
|
assert decoded.width == width
|
|
# image_slice = torch.from_numpy(np.array(inputs["image"])[0, -3:, -3:].flatten())
|
|
# decoded_slice = torch.from_numpy(np.array(decoded)[0, -3:, -3:].flatten())
|
|
# TODO: how to test this? encode->decode is lossy. expected slice of encoded latent?
|
|
|
|
|
|
# The tests below hit live HF Inference Endpoints, which are not part of the fast CI contract, so they are
|
|
# gated behind `RUN_SLOW` instead of running on every push.
|
|
@slow
|
|
class TestRemoteAutoencoderKLSDv1(RemoteAutoencoderKLEncodeMixin):
|
|
channels = 4
|
|
endpoint = ENCODE_ENDPOINT_SD_V1
|
|
decode_endpoint = DECODE_ENDPOINT_SD_V1
|
|
dtype = torch.float16
|
|
scaling_factor = 0.18215
|
|
shift_factor = None
|
|
|
|
|
|
@slow
|
|
class TestRemoteAutoencoderKLSDXL(RemoteAutoencoderKLEncodeMixin):
|
|
channels = 4
|
|
endpoint = ENCODE_ENDPOINT_SD_XL
|
|
decode_endpoint = DECODE_ENDPOINT_SD_XL
|
|
dtype = torch.float16
|
|
scaling_factor = 0.13025
|
|
shift_factor = None
|
|
|
|
|
|
@slow
|
|
class TestRemoteAutoencoderKLFlux(RemoteAutoencoderKLEncodeMixin):
|
|
channels = 16
|
|
endpoint = ENCODE_ENDPOINT_FLUX
|
|
decode_endpoint = DECODE_ENDPOINT_FLUX
|
|
dtype = torch.bfloat16
|
|
scaling_factor = 0.3611
|
|
shift_factor = 0.1159
|
|
|
|
|
|
class RemoteAutoencoderKLEncodeSlowTestMixin:
|
|
channels: int = 4
|
|
endpoint: str = None
|
|
decode_endpoint: str = None
|
|
dtype: torch.dtype = None
|
|
scaling_factor: float = None
|
|
shift_factor: float = None
|
|
image: PIL.Image.Image = None
|
|
|
|
def get_dummy_inputs(self):
|
|
if self.image is None:
|
|
self.image = load_image(IMAGE)
|
|
inputs = {
|
|
"endpoint": self.endpoint,
|
|
"image": self.image,
|
|
"scaling_factor": self.scaling_factor,
|
|
"shift_factor": self.shift_factor,
|
|
}
|
|
return inputs
|
|
|
|
@ENDPOINTS_GONE
|
|
def test_multi_res(self, tmp_path):
|
|
inputs = self.get_dummy_inputs()
|
|
for height in {
|
|
320,
|
|
512,
|
|
640,
|
|
704,
|
|
896,
|
|
1024,
|
|
1208,
|
|
1384,
|
|
1536,
|
|
1608,
|
|
1864,
|
|
2048,
|
|
}:
|
|
for width in {
|
|
320,
|
|
512,
|
|
640,
|
|
704,
|
|
896,
|
|
1024,
|
|
1208,
|
|
1384,
|
|
1536,
|
|
1608,
|
|
1864,
|
|
2048,
|
|
}:
|
|
inputs["image"] = inputs["image"].resize(
|
|
(
|
|
width,
|
|
height,
|
|
)
|
|
)
|
|
output = remote_encode(**inputs)
|
|
assert list(output.shape) == [1, self.channels, height // 8, width // 8]
|
|
decoded = remote_decode(
|
|
tensor=output,
|
|
endpoint=self.decode_endpoint,
|
|
scaling_factor=self.scaling_factor,
|
|
shift_factor=self.shift_factor,
|
|
image_format="png",
|
|
)
|
|
assert decoded.height == height
|
|
assert decoded.width == width
|
|
decoded.save(tmp_path / f"test_multi_res_{height}_{width}.png")
|
|
|
|
|
|
@slow
|
|
class TestRemoteAutoencoderKLSDv1Slow(RemoteAutoencoderKLEncodeSlowTestMixin):
|
|
endpoint = ENCODE_ENDPOINT_SD_V1
|
|
decode_endpoint = DECODE_ENDPOINT_SD_V1
|
|
dtype = torch.float16
|
|
scaling_factor = 0.18215
|
|
shift_factor = None
|
|
|
|
|
|
@slow
|
|
class TestRemoteAutoencoderKLSDXLSlow(RemoteAutoencoderKLEncodeSlowTestMixin):
|
|
endpoint = ENCODE_ENDPOINT_SD_XL
|
|
decode_endpoint = DECODE_ENDPOINT_SD_XL
|
|
dtype = torch.float16
|
|
scaling_factor = 0.13025
|
|
shift_factor = None
|
|
|
|
|
|
@slow
|
|
class TestRemoteAutoencoderKLFluxSlow(RemoteAutoencoderKLEncodeSlowTestMixin):
|
|
channels = 16
|
|
endpoint = ENCODE_ENDPOINT_FLUX
|
|
decode_endpoint = DECODE_ENDPOINT_FLUX
|
|
dtype = torch.bfloat16
|
|
scaling_factor = 0.3611
|
|
shift_factor = 0.1159
|