mirror of
https://github.com/huggingface/diffusers.git
synced 2025-12-17 09:54:41 +08:00
Compare commits
5 Commits
animatedif
...
nightly-te
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49fc45474c | ||
|
|
50e1accd45 | ||
|
|
940b8e0358 | ||
|
|
b2add10d13 | ||
|
|
815d882217 |
1
.github/workflows/nightly_tests.yml
vendored
1
.github/workflows/nightly_tests.yml
vendored
@@ -116,6 +116,7 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: bash
|
shell: bash
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
max-parallel: 2
|
max-parallel: 2
|
||||||
matrix:
|
matrix:
|
||||||
module: [models, schedulers, lora, others, single_file, examples]
|
module: [models, schedulers, lora, others, single_file, examples]
|
||||||
|
|||||||
2
.github/workflows/push_tests.yml
vendored
2
.github/workflows/push_tests.yml
vendored
@@ -112,6 +112,8 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: bash
|
shell: bash
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 2
|
||||||
matrix:
|
matrix:
|
||||||
module: [models, schedulers, lora, others, single_file]
|
module: [models, schedulers, lora, others, single_file]
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ import torch
|
|||||||
model_id = "path-to-your-trained-model"
|
model_id = "path-to-your-trained-model"
|
||||||
pipe = StableDiffusionPipeline.from_pretrained(model_id,torch_dtype=torch.float16).to("cuda")
|
pipe = StableDiffusionPipeline.from_pretrained(model_id,torch_dtype=torch.float16).to("cuda")
|
||||||
|
|
||||||
|
repo_id_embeds = "path-to-your-learned-embeds"
|
||||||
|
pipe.load_textual_inversion(repo_id_embeds)
|
||||||
|
|
||||||
prompt = "A <cat-toy> backpack"
|
prompt = "A <cat-toy> backpack"
|
||||||
|
|
||||||
image = pipe(prompt, num_inference_steps=50, guidance_scale=7.5).images[0]
|
image = pipe(prompt, num_inference_steps=50, guidance_scale=7.5).images[0]
|
||||||
|
|||||||
@@ -89,49 +89,44 @@ for library in LOADABLE_CLASSES:
|
|||||||
ALL_IMPORTABLE_CLASSES.update(LOADABLE_CLASSES[library])
|
ALL_IMPORTABLE_CLASSES.update(LOADABLE_CLASSES[library])
|
||||||
|
|
||||||
|
|
||||||
def is_safetensors_compatible(filenames, variant=None, passed_components=None) -> bool:
|
def is_safetensors_compatible(filenames, passed_components=None) -> bool:
|
||||||
"""
|
"""
|
||||||
Checking for safetensors compatibility:
|
Checking for safetensors compatibility:
|
||||||
- By default, all models are saved with the default pytorch serialization, so we use the list of default pytorch
|
- The model is safetensors compatible only if there is a safetensors file for each model component present in
|
||||||
files to know which safetensors files are needed.
|
filenames.
|
||||||
- The model is safetensors compatible only if there is a matching safetensors file for every default pytorch file.
|
|
||||||
|
|
||||||
Converting default pytorch serialized filenames to safetensors serialized filenames:
|
Converting default pytorch serialized filenames to safetensors serialized filenames:
|
||||||
- For models from the diffusers library, just replace the ".bin" extension with ".safetensors"
|
- For models from the diffusers library, just replace the ".bin" extension with ".safetensors"
|
||||||
- For models from the transformers library, the filename changes from "pytorch_model" to "model", and the ".bin"
|
- For models from the transformers library, the filename changes from "pytorch_model" to "model", and the ".bin"
|
||||||
extension is replaced with ".safetensors"
|
extension is replaced with ".safetensors"
|
||||||
"""
|
"""
|
||||||
pt_filenames = []
|
|
||||||
|
|
||||||
sf_filenames = set()
|
|
||||||
|
|
||||||
passed_components = passed_components or []
|
passed_components = passed_components or []
|
||||||
|
|
||||||
|
# extract all components of the pipeline and their associated files
|
||||||
|
components = {}
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
_, extension = os.path.splitext(filename)
|
if not len(filename.split("/")) == 2:
|
||||||
|
|
||||||
if len(filename.split("/")) == 2 and filename.split("/")[0] in passed_components:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if extension == ".bin":
|
component, component_filename = filename.split("/")
|
||||||
pt_filenames.append(os.path.normpath(filename))
|
if component in passed_components:
|
||||||
elif extension == ".safetensors":
|
continue
|
||||||
sf_filenames.add(os.path.normpath(filename))
|
|
||||||
|
|
||||||
for filename in pt_filenames:
|
components.setdefault(component, [])
|
||||||
# filename = 'foo/bar/baz.bam' -> path = 'foo/bar', filename = 'baz', extension = '.bam'
|
components[component].append(component_filename)
|
||||||
path, filename = os.path.split(filename)
|
|
||||||
filename, extension = os.path.splitext(filename)
|
|
||||||
|
|
||||||
if filename.startswith("pytorch_model"):
|
# iterate over all files of a component
|
||||||
filename = filename.replace("pytorch_model", "model")
|
# check if safetensor files exist for that component
|
||||||
else:
|
# if variant is provided check if the variant of the safetensors exists
|
||||||
filename = filename
|
for component, component_filenames in components.items():
|
||||||
|
matches = []
|
||||||
|
for component_filename in component_filenames:
|
||||||
|
filename, extension = os.path.splitext(component_filename)
|
||||||
|
|
||||||
expected_sf_filename = os.path.normpath(os.path.join(path, filename))
|
match_exists = extension == ".safetensors"
|
||||||
expected_sf_filename = f"{expected_sf_filename}.safetensors"
|
matches.append(match_exists)
|
||||||
if expected_sf_filename not in sf_filenames:
|
|
||||||
logger.warning(f"{expected_sf_filename} not found")
|
if not any(matches):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1416,18 +1416,14 @@ class DiffusionPipeline(ConfigMixin, PushToHubMixin):
|
|||||||
if (
|
if (
|
||||||
use_safetensors
|
use_safetensors
|
||||||
and not allow_pickle
|
and not allow_pickle
|
||||||
and not is_safetensors_compatible(
|
and not is_safetensors_compatible(model_filenames, passed_components=passed_components)
|
||||||
model_filenames, variant=variant, passed_components=passed_components
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
raise EnvironmentError(
|
raise EnvironmentError(
|
||||||
f"Could not find the necessary `safetensors` weights in {model_filenames} (variant={variant})"
|
f"Could not find the necessary `safetensors` weights in {model_filenames} (variant={variant})"
|
||||||
)
|
)
|
||||||
if from_flax:
|
if from_flax:
|
||||||
ignore_patterns = ["*.bin", "*.safetensors", "*.onnx", "*.pb"]
|
ignore_patterns = ["*.bin", "*.safetensors", "*.onnx", "*.pb"]
|
||||||
elif use_safetensors and is_safetensors_compatible(
|
elif use_safetensors and is_safetensors_compatible(model_filenames, passed_components=passed_components):
|
||||||
model_filenames, variant=variant, passed_components=passed_components
|
|
||||||
):
|
|
||||||
ignore_patterns = ["*.bin", "*.msgpack"]
|
ignore_patterns = ["*.bin", "*.msgpack"]
|
||||||
|
|
||||||
use_onnx = use_onnx if use_onnx is not None else pipeline_class._is_onnx
|
use_onnx = use_onnx if use_onnx is not None else pipeline_class._is_onnx
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ from utils import PeftLoraLoaderMixinTests # noqa: E402
|
|||||||
@require_peft_backend
|
@require_peft_backend
|
||||||
class SD3LoRATests(unittest.TestCase, PeftLoraLoaderMixinTests):
|
class SD3LoRATests(unittest.TestCase, PeftLoraLoaderMixinTests):
|
||||||
pipeline_class = StableDiffusion3Pipeline
|
pipeline_class = StableDiffusion3Pipeline
|
||||||
scheduler_cls = FlowMatchEulerDiscreteScheduler()
|
scheduler_cls = FlowMatchEulerDiscreteScheduler
|
||||||
scheduler_kwargs = {}
|
scheduler_kwargs = {}
|
||||||
uses_flow_matching = True
|
uses_flow_matching = True
|
||||||
transformer_kwargs = {
|
transformer_kwargs = {
|
||||||
@@ -80,8 +80,7 @@ class SD3LoRATests(unittest.TestCase, PeftLoraLoaderMixinTests):
|
|||||||
Related PR: https://github.com/huggingface/diffusers/pull/8584
|
Related PR: https://github.com/huggingface/diffusers/pull/8584
|
||||||
"""
|
"""
|
||||||
components = self.get_dummy_components()
|
components = self.get_dummy_components()
|
||||||
|
pipe = self.pipeline_class(**components[0])
|
||||||
pipe = self.pipeline_class(**components)
|
|
||||||
pipe = pipe.to(torch_device)
|
pipe = pipe.to(torch_device)
|
||||||
pipe.set_progress_bar_config(disable=None)
|
pipe.set_progress_bar_config(disable=None)
|
||||||
|
|
||||||
|
|||||||
@@ -124,71 +124,6 @@ class LoraSDXLIntegrationTests(unittest.TestCase):
|
|||||||
gc.collect()
|
gc.collect()
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
|
|
||||||
def test_sdxl_0_9_lora_one(self):
|
|
||||||
generator = torch.Generator().manual_seed(0)
|
|
||||||
|
|
||||||
pipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-0.9")
|
|
||||||
lora_model_id = "hf-internal-testing/sdxl-0.9-daiton-lora"
|
|
||||||
lora_filename = "daiton-xl-lora-test.safetensors"
|
|
||||||
pipe.load_lora_weights(lora_model_id, weight_name=lora_filename)
|
|
||||||
pipe.enable_model_cpu_offload()
|
|
||||||
|
|
||||||
images = pipe(
|
|
||||||
"masterpiece, best quality, mountain", output_type="np", generator=generator, num_inference_steps=2
|
|
||||||
).images
|
|
||||||
|
|
||||||
images = images[0, -3:, -3:, -1].flatten()
|
|
||||||
expected = np.array([0.3838, 0.3482, 0.3588, 0.3162, 0.319, 0.3369, 0.338, 0.3366, 0.3213])
|
|
||||||
|
|
||||||
max_diff = numpy_cosine_similarity_distance(expected, images)
|
|
||||||
assert max_diff < 1e-3
|
|
||||||
pipe.unload_lora_weights()
|
|
||||||
release_memory(pipe)
|
|
||||||
|
|
||||||
def test_sdxl_0_9_lora_two(self):
|
|
||||||
generator = torch.Generator().manual_seed(0)
|
|
||||||
|
|
||||||
pipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-0.9")
|
|
||||||
lora_model_id = "hf-internal-testing/sdxl-0.9-costumes-lora"
|
|
||||||
lora_filename = "saijo.safetensors"
|
|
||||||
pipe.load_lora_weights(lora_model_id, weight_name=lora_filename)
|
|
||||||
pipe.enable_model_cpu_offload()
|
|
||||||
|
|
||||||
images = pipe(
|
|
||||||
"masterpiece, best quality, mountain", output_type="np", generator=generator, num_inference_steps=2
|
|
||||||
).images
|
|
||||||
|
|
||||||
images = images[0, -3:, -3:, -1].flatten()
|
|
||||||
expected = np.array([0.3137, 0.3269, 0.3355, 0.255, 0.2577, 0.2563, 0.2679, 0.2758, 0.2626])
|
|
||||||
|
|
||||||
max_diff = numpy_cosine_similarity_distance(expected, images)
|
|
||||||
assert max_diff < 1e-3
|
|
||||||
|
|
||||||
pipe.unload_lora_weights()
|
|
||||||
release_memory(pipe)
|
|
||||||
|
|
||||||
def test_sdxl_0_9_lora_three(self):
|
|
||||||
generator = torch.Generator().manual_seed(0)
|
|
||||||
|
|
||||||
pipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-0.9")
|
|
||||||
lora_model_id = "hf-internal-testing/sdxl-0.9-kamepan-lora"
|
|
||||||
lora_filename = "kame_sdxl_v2-000020-16rank.safetensors"
|
|
||||||
pipe.load_lora_weights(lora_model_id, weight_name=lora_filename)
|
|
||||||
pipe.enable_model_cpu_offload()
|
|
||||||
|
|
||||||
images = pipe(
|
|
||||||
"masterpiece, best quality, mountain", output_type="np", generator=generator, num_inference_steps=2
|
|
||||||
).images
|
|
||||||
|
|
||||||
images = images[0, -3:, -3:, -1].flatten()
|
|
||||||
expected = np.array([0.4015, 0.3761, 0.3616, 0.3745, 0.3462, 0.3337, 0.3564, 0.3649, 0.3468])
|
|
||||||
|
|
||||||
max_diff = numpy_cosine_similarity_distance(expected, images)
|
|
||||||
assert max_diff < 5e-3
|
|
||||||
|
|
||||||
pipe.unload_lora_weights()
|
|
||||||
release_memory(pipe)
|
|
||||||
|
|
||||||
def test_sdxl_1_0_lora(self):
|
def test_sdxl_1_0_lora(self):
|
||||||
generator = torch.Generator("cpu").manual_seed(0)
|
generator = torch.Generator("cpu").manual_seed(0)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from ..test_modeling_common import ModelTesterMixin
|
|||||||
enable_full_determinism()
|
enable_full_determinism()
|
||||||
|
|
||||||
|
|
||||||
class SD3TransformerTests(ModelTesterMixin, unittest.TestCase):
|
class AuraFlowTransformerTests(ModelTesterMixin, unittest.TestCase):
|
||||||
model_class = AuraFlowTransformer2DModel
|
model_class = AuraFlowTransformer2DModel
|
||||||
main_input_name = "hidden_states"
|
main_input_name = "hidden_states"
|
||||||
# We override the items here because the transformer under consideration is small.
|
# We override the items here because the transformer under consideration is small.
|
||||||
@@ -73,3 +73,7 @@ class SD3TransformerTests(ModelTesterMixin, unittest.TestCase):
|
|||||||
}
|
}
|
||||||
inputs_dict = self.dummy_input
|
inputs_dict = self.dummy_input
|
||||||
return init_dict, inputs_dict
|
return init_dict, inputs_dict
|
||||||
|
|
||||||
|
@unittest.skip("AuraFlowTransformer2DModel uses its own dedicated attention processor. This test does not apply")
|
||||||
|
def test_set_attn_processor_for_determinism(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -76,3 +76,7 @@ class SD3TransformerTests(ModelTesterMixin, unittest.TestCase):
|
|||||||
}
|
}
|
||||||
inputs_dict = self.dummy_input
|
inputs_dict = self.dummy_input
|
||||||
return init_dict, inputs_dict
|
return init_dict, inputs_dict
|
||||||
|
|
||||||
|
@unittest.skip("SD3Transformer2DModel uses a dedicated attention processor. This test doesn't apply")
|
||||||
|
def test_set_attn_processor_for_determinism(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -163,3 +163,7 @@ class AuraFlowPipelineFastTests(unittest.TestCase, PipelineTesterMixin):
|
|||||||
assert np.allclose(
|
assert np.allclose(
|
||||||
original_image_slice, image_slice_disabled, atol=1e-2, rtol=1e-2
|
original_image_slice, image_slice_disabled, atol=1e-2, rtol=1e-2
|
||||||
), "Original outputs should match when fused QKV projections are disabled."
|
), "Original outputs should match when fused QKV projections are disabled."
|
||||||
|
|
||||||
|
@unittest.skip("xformers attention processor does not exist for AuraFlow")
|
||||||
|
def test_xformers_attention_forwardGenerator_pass(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -119,6 +119,10 @@ class LuminaText2ImgPipelinePipelineFastTests(unittest.TestCase, PipelineTesterM
|
|||||||
max_diff = np.abs(output_with_prompt - output_with_embeds).max()
|
max_diff = np.abs(output_with_prompt - output_with_embeds).max()
|
||||||
assert max_diff < 1e-4
|
assert max_diff < 1e-4
|
||||||
|
|
||||||
|
@unittest.skip("xformers attention processor does not exist for Lumina")
|
||||||
|
def test_xformers_attention_forwardGenerator_pass(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@slow
|
@slow
|
||||||
@require_torch_gpu
|
@require_torch_gpu
|
||||||
|
|||||||
@@ -68,25 +68,21 @@ class IsSafetensorsCompatibleTests(unittest.TestCase):
|
|||||||
"unet/diffusion_pytorch_model.fp16.bin",
|
"unet/diffusion_pytorch_model.fp16.bin",
|
||||||
"unet/diffusion_pytorch_model.fp16.safetensors",
|
"unet/diffusion_pytorch_model.fp16.safetensors",
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
self.assertTrue(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_diffusers_model_is_compatible_variant(self):
|
def test_diffusers_model_is_compatible_variant(self):
|
||||||
filenames = [
|
filenames = [
|
||||||
"unet/diffusion_pytorch_model.fp16.bin",
|
"unet/diffusion_pytorch_model.fp16.bin",
|
||||||
"unet/diffusion_pytorch_model.fp16.safetensors",
|
"unet/diffusion_pytorch_model.fp16.safetensors",
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
self.assertTrue(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_diffusers_model_is_compatible_variant_partial(self):
|
def test_diffusers_model_is_compatible_variant_mixed(self):
|
||||||
# pass variant but use the non-variant filenames
|
|
||||||
filenames = [
|
filenames = [
|
||||||
"unet/diffusion_pytorch_model.bin",
|
"unet/diffusion_pytorch_model.bin",
|
||||||
"unet/diffusion_pytorch_model.safetensors",
|
"unet/diffusion_pytorch_model.fp16.safetensors",
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
self.assertTrue(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_diffusers_model_is_not_compatible_variant(self):
|
def test_diffusers_model_is_not_compatible_variant(self):
|
||||||
filenames = [
|
filenames = [
|
||||||
@@ -99,25 +95,14 @@ class IsSafetensorsCompatibleTests(unittest.TestCase):
|
|||||||
"unet/diffusion_pytorch_model.fp16.bin",
|
"unet/diffusion_pytorch_model.fp16.bin",
|
||||||
# Removed: 'unet/diffusion_pytorch_model.fp16.safetensors',
|
# Removed: 'unet/diffusion_pytorch_model.fp16.safetensors',
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertFalse(is_safetensors_compatible(filenames))
|
||||||
self.assertFalse(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_transformer_model_is_compatible_variant(self):
|
def test_transformer_model_is_compatible_variant(self):
|
||||||
filenames = [
|
filenames = [
|
||||||
"text_encoder/pytorch_model.fp16.bin",
|
"text_encoder/pytorch_model.fp16.bin",
|
||||||
"text_encoder/model.fp16.safetensors",
|
"text_encoder/model.fp16.safetensors",
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
self.assertTrue(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_transformer_model_is_compatible_variant_partial(self):
|
|
||||||
# pass variant but use the non-variant filenames
|
|
||||||
filenames = [
|
|
||||||
"text_encoder/pytorch_model.bin",
|
|
||||||
"text_encoder/model.safetensors",
|
|
||||||
]
|
|
||||||
variant = "fp16"
|
|
||||||
self.assertTrue(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
|
||||||
def test_transformer_model_is_not_compatible_variant(self):
|
def test_transformer_model_is_not_compatible_variant(self):
|
||||||
filenames = [
|
filenames = [
|
||||||
@@ -126,9 +111,45 @@ class IsSafetensorsCompatibleTests(unittest.TestCase):
|
|||||||
"vae/diffusion_pytorch_model.fp16.bin",
|
"vae/diffusion_pytorch_model.fp16.bin",
|
||||||
"vae/diffusion_pytorch_model.fp16.safetensors",
|
"vae/diffusion_pytorch_model.fp16.safetensors",
|
||||||
"text_encoder/pytorch_model.fp16.bin",
|
"text_encoder/pytorch_model.fp16.bin",
|
||||||
# 'text_encoder/model.fp16.safetensors',
|
|
||||||
"unet/diffusion_pytorch_model.fp16.bin",
|
"unet/diffusion_pytorch_model.fp16.bin",
|
||||||
"unet/diffusion_pytorch_model.fp16.safetensors",
|
"unet/diffusion_pytorch_model.fp16.safetensors",
|
||||||
]
|
]
|
||||||
variant = "fp16"
|
self.assertFalse(is_safetensors_compatible(filenames))
|
||||||
self.assertFalse(is_safetensors_compatible(filenames, variant=variant))
|
|
||||||
|
def test_transformers_is_compatible_sharded(self):
|
||||||
|
filenames = [
|
||||||
|
"text_encoder/pytorch_model.bin",
|
||||||
|
"text_encoder/model-00001-of-00002.safetensors",
|
||||||
|
"text_encoder/model-00002-of-00002.safetensors",
|
||||||
|
]
|
||||||
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
|
|
||||||
|
def test_transformers_is_compatible_variant_sharded(self):
|
||||||
|
filenames = [
|
||||||
|
"text_encoder/pytorch_model.bin",
|
||||||
|
"text_encoder/model.fp16-00001-of-00002.safetensors",
|
||||||
|
"text_encoder/model.fp16-00001-of-00002.safetensors",
|
||||||
|
]
|
||||||
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
|
|
||||||
|
def test_diffusers_is_compatible_sharded(self):
|
||||||
|
filenames = [
|
||||||
|
"unet/diffusion_pytorch_model.bin",
|
||||||
|
"unet/diffusion_pytorch_model-00001-of-00002.safetensors",
|
||||||
|
"unet/diffusion_pytorch_model-00002-of-00002.safetensors",
|
||||||
|
]
|
||||||
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
|
|
||||||
|
def test_diffusers_is_compatible_variant_sharded(self):
|
||||||
|
filenames = [
|
||||||
|
"unet/diffusion_pytorch_model.bin",
|
||||||
|
"unet/diffusion_pytorch_model.fp16-00001-of-00002.safetensors",
|
||||||
|
"unet/diffusion_pytorch_model.fp16-00001-of-00002.safetensors",
|
||||||
|
]
|
||||||
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
|
|
||||||
|
def test_diffusers_is_compatible_only_variants(self):
|
||||||
|
filenames = [
|
||||||
|
"unet/diffusion_pytorch_model.fp16.safetensors",
|
||||||
|
]
|
||||||
|
self.assertTrue(is_safetensors_compatible(filenames))
|
||||||
|
|||||||
@@ -551,37 +551,94 @@ class DownloadTests(unittest.TestCase):
|
|||||||
assert sum(f.endswith(this_format) and not f.endswith(f"{variant}{this_format}") for f in files) == 3
|
assert sum(f.endswith(this_format) and not f.endswith(f"{variant}{this_format}") for f in files) == 3
|
||||||
assert not any(f.endswith(other_format) for f in files)
|
assert not any(f.endswith(other_format) for f in files)
|
||||||
|
|
||||||
def test_download_broken_variant(self):
|
def test_download_safetensors_only_variant_exists_for_model(self):
|
||||||
for use_safetensors in [False, True]:
|
variant = None
|
||||||
# text encoder is missing no variant and "no_ema" variant weights, so the following can't work
|
use_safetensors = True
|
||||||
for variant in [None, "no_ema"]:
|
|
||||||
with self.assertRaises(OSError) as error_context:
|
|
||||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
||||||
tmpdirname = StableDiffusionPipeline.from_pretrained(
|
|
||||||
"hf-internal-testing/stable-diffusion-broken-variants",
|
|
||||||
cache_dir=tmpdirname,
|
|
||||||
variant=variant,
|
|
||||||
use_safetensors=use_safetensors,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert "Error no file name" in str(error_context.exception)
|
# text encoder is missing no variant weights, so the following can't work
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
# text encoder has fp16 variants so we can load it
|
with self.assertRaises(OSError) as error_context:
|
||||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
tmpdirname = StableDiffusionPipeline.from_pretrained(
|
||||||
tmpdirname = StableDiffusionPipeline.download(
|
|
||||||
"hf-internal-testing/stable-diffusion-broken-variants",
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
use_safetensors=use_safetensors,
|
|
||||||
cache_dir=tmpdirname,
|
cache_dir=tmpdirname,
|
||||||
variant="fp16",
|
variant=variant,
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
|
)
|
||||||
|
assert "Error no file name" in str(error_context.exception)
|
||||||
|
|
||||||
|
# text encoder has fp16 variants so we can load it
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
tmpdirname = StableDiffusionPipeline.download(
|
||||||
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
|
cache_dir=tmpdirname,
|
||||||
|
variant="fp16",
|
||||||
|
)
|
||||||
|
all_root_files = [t[-1] for t in os.walk(tmpdirname)]
|
||||||
|
files = [item for sublist in all_root_files for item in sublist]
|
||||||
|
# None of the downloaded files should be a non-variant file even if we have some here:
|
||||||
|
# https://huggingface.co/hf-internal-testing/stable-diffusion-broken-variants/tree/main/unet
|
||||||
|
assert len(files) == 15, f"We should only download 15 files, not {len(files)}"
|
||||||
|
|
||||||
|
def test_download_bin_only_variant_exists_for_model(self):
|
||||||
|
variant = None
|
||||||
|
use_safetensors = False
|
||||||
|
|
||||||
|
# text encoder is missing Non-variant weights, so the following can't work
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
with self.assertRaises(OSError) as error_context:
|
||||||
|
tmpdirname = StableDiffusionPipeline.from_pretrained(
|
||||||
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
|
cache_dir=tmpdirname,
|
||||||
|
variant=variant,
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
|
)
|
||||||
|
assert "Error no file name" in str(error_context.exception)
|
||||||
|
|
||||||
|
# text encoder has fp16 variants so we can load it
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
tmpdirname = StableDiffusionPipeline.download(
|
||||||
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
|
cache_dir=tmpdirname,
|
||||||
|
variant="fp16",
|
||||||
|
)
|
||||||
|
all_root_files = [t[-1] for t in os.walk(tmpdirname)]
|
||||||
|
files = [item for sublist in all_root_files for item in sublist]
|
||||||
|
# None of the downloaded files should be a non-variant file even if we have some here:
|
||||||
|
# https://huggingface.co/hf-internal-testing/stable-diffusion-broken-variants/tree/main/unet
|
||||||
|
assert len(files) == 15, f"We should only download 15 files, not {len(files)}"
|
||||||
|
|
||||||
|
def test_download_safetensors_variant_does_not_exist_for_model(self):
|
||||||
|
variant = "no_ema"
|
||||||
|
use_safetensors = True
|
||||||
|
|
||||||
|
# text encoder is missing no_ema variant weights, so the following can't work
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
with self.assertRaises(OSError) as error_context:
|
||||||
|
tmpdirname = StableDiffusionPipeline.from_pretrained(
|
||||||
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
|
cache_dir=tmpdirname,
|
||||||
|
variant=variant,
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
)
|
)
|
||||||
|
|
||||||
all_root_files = [t[-1] for t in os.walk(tmpdirname)]
|
assert "Error no file name" in str(error_context.exception)
|
||||||
files = [item for sublist in all_root_files for item in sublist]
|
|
||||||
|
|
||||||
# None of the downloaded files should be a non-variant file even if we have some here:
|
def test_download_bin_variant_does_not_exist_for_model(self):
|
||||||
# https://huggingface.co/hf-internal-testing/stable-diffusion-broken-variants/tree/main/unet
|
variant = "no_ema"
|
||||||
assert len(files) == 15, f"We should only download 15 files, not {len(files)}"
|
use_safetensors = False
|
||||||
# only unet has "no_ema" variant
|
|
||||||
|
# text encoder is missing no_ema variant weights, so the following can't work
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
|
with self.assertRaises(OSError) as error_context:
|
||||||
|
tmpdirname = StableDiffusionPipeline.from_pretrained(
|
||||||
|
"hf-internal-testing/stable-diffusion-broken-variants",
|
||||||
|
cache_dir=tmpdirname,
|
||||||
|
variant=variant,
|
||||||
|
use_safetensors=use_safetensors,
|
||||||
|
)
|
||||||
|
assert "Error no file name" in str(error_context.exception)
|
||||||
|
|
||||||
def test_local_save_load_index(self):
|
def test_local_save_load_index(self):
|
||||||
prompt = "hello"
|
prompt = "hello"
|
||||||
|
|||||||
@@ -20,12 +20,7 @@ import numpy as np
|
|||||||
import torch
|
import torch
|
||||||
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer
|
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer
|
||||||
|
|
||||||
from diffusers import (
|
from diffusers import AutoencoderKL, DDIMScheduler, TextToVideoSDPipeline, UNet3DConditionModel
|
||||||
AutoencoderKL,
|
|
||||||
DDIMScheduler,
|
|
||||||
TextToVideoSDPipeline,
|
|
||||||
UNet3DConditionModel,
|
|
||||||
)
|
|
||||||
from diffusers.utils import is_xformers_available
|
from diffusers.utils import is_xformers_available
|
||||||
from diffusers.utils.testing_utils import (
|
from diffusers.utils.testing_utils import (
|
||||||
enable_full_determinism,
|
enable_full_determinism,
|
||||||
@@ -64,7 +59,7 @@ class TextToVideoSDPipelineFastTests(PipelineTesterMixin, SDFunctionTesterMixin,
|
|||||||
def get_dummy_components(self):
|
def get_dummy_components(self):
|
||||||
torch.manual_seed(0)
|
torch.manual_seed(0)
|
||||||
unet = UNet3DConditionModel(
|
unet = UNet3DConditionModel(
|
||||||
block_out_channels=(4, 8),
|
block_out_channels=(8, 8),
|
||||||
layers_per_block=1,
|
layers_per_block=1,
|
||||||
sample_size=32,
|
sample_size=32,
|
||||||
in_channels=4,
|
in_channels=4,
|
||||||
@@ -134,10 +129,7 @@ class TextToVideoSDPipelineFastTests(PipelineTesterMixin, SDFunctionTesterMixin,
|
|||||||
return inputs
|
return inputs
|
||||||
|
|
||||||
def test_dict_tuple_outputs_equivalent(self):
|
def test_dict_tuple_outputs_equivalent(self):
|
||||||
expected_slice = None
|
return super().test_dict_tuple_outputs_equivalent()
|
||||||
if torch_device == "cpu":
|
|
||||||
expected_slice = np.array([0.4903, 0.5649, 0.5504, 0.5179, 0.4821, 0.5466, 0.4131, 0.5052, 0.5077])
|
|
||||||
return super().test_dict_tuple_outputs_equivalent(expected_slice=expected_slice)
|
|
||||||
|
|
||||||
def test_text_to_video_default_case(self):
|
def test_text_to_video_default_case(self):
|
||||||
device = "cpu" # ensure determinism for the device-dependent torch.Generator
|
device = "cpu" # ensure determinism for the device-dependent torch.Generator
|
||||||
@@ -151,9 +143,8 @@ class TextToVideoSDPipelineFastTests(PipelineTesterMixin, SDFunctionTesterMixin,
|
|||||||
frames = sd_pipe(**inputs).frames
|
frames = sd_pipe(**inputs).frames
|
||||||
|
|
||||||
image_slice = frames[0][0][-3:, -3:, -1]
|
image_slice = frames[0][0][-3:, -3:, -1]
|
||||||
|
|
||||||
assert frames[0][0].shape == (32, 32, 3)
|
assert frames[0][0].shape == (32, 32, 3)
|
||||||
expected_slice = np.array([0.7537, 0.1752, 0.6157, 0.5508, 0.4240, 0.4110, 0.4838, 0.5648, 0.5094])
|
expected_slice = np.array([0.8093, 0.2751, 0.6976, 0.5927, 0.4616, 0.4336, 0.5094, 0.5683, 0.4796])
|
||||||
|
|
||||||
assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2
|
assert np.abs(image_slice.flatten() - expected_slice).max() < 1e-2
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user