Skip to content

Commit 96dd323

Browse files
authored
Disable scheduler, tokenizer, feature extractor loading when provided (#245)
* Disable scheduler, tokenizer, feature extractor loading when given * add test * fix style * fix documentation * reduce generated number of images
1 parent d1706a4 commit 96dd323

File tree

4 files changed

+33
-29
lines changed

4 files changed

+33
-29
lines changed

docs/source/inference.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ Stable Diffusion models can also be used when running inference with OpenVINO. W
134134
are exported to the OpenVINO format, they are decomposed into three components that are later combined during inference:
135135
- The text encoder
136136
- The U-NET
137+
- The VAE encoder
137138
- The VAE decoder
138139

139140
Make sure you have 🤗 Diffusers installed.

optimum/intel/openvino/modeling_diffusion.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ def _from_pretrained(
197197
model_id = str(model_id)
198198
sub_models_to_load, _, _ = cls.extract_init_dict(config)
199199
sub_models_names = set(sub_models_to_load.keys()).intersection({"feature_extractor", "tokenizer", "scheduler"})
200-
sub_models = {}
201200

202201
if not os.path.isdir(model_id):
203202
patterns = set(config.keys())
@@ -231,16 +230,19 @@ def _from_pretrained(
231230
new_model_save_dir = Path(model_id)
232231

233232
for name in sub_models_names:
233+
# Check if the subcomponent needs to be loaded
234+
if kwargs.get(name, None) is not None:
235+
continue
234236
library_name, library_classes = sub_models_to_load[name]
235237
if library_classes is not None:
236238
library = importlib.import_module(library_name)
237239
class_obj = getattr(library, library_classes)
238240
load_method = getattr(class_obj, "from_pretrained")
239241
# Check if the module is in a subdirectory
240242
if (new_model_save_dir / name).is_dir():
241-
sub_models[name] = load_method(new_model_save_dir / name)
243+
kwargs[name] = load_method(new_model_save_dir / name)
242244
else:
243-
sub_models[name] = load_method(new_model_save_dir)
245+
kwargs[name] = load_method(new_model_save_dir)
244246

245247
vae_decoder = cls.load_model(
246248
new_model_save_dir / DIFFUSION_MODEL_VAE_DECODER_SUBFOLDER / vae_decoder_file_name
@@ -260,9 +262,9 @@ def _from_pretrained(
260262
text_encoder=text_encoder,
261263
unet=unet,
262264
config=config,
263-
tokenizer=sub_models["tokenizer"],
264-
scheduler=sub_models["scheduler"],
265-
feature_extractor=sub_models.pop("feature_extractor", None),
265+
tokenizer=kwargs.pop("tokenizer"),
266+
scheduler=kwargs.pop("scheduler"),
267+
feature_extractor=kwargs.pop("feature_extractor", None),
266268
vae_encoder=vae_encoder,
267269
model_save_dir=model_save_dir,
268270
**kwargs,
@@ -279,6 +281,9 @@ def _from_transformers(
279281
cache_dir: Optional[str] = None,
280282
local_files_only: bool = False,
281283
task: Optional[str] = None,
284+
tokenizer: "CLIPTokenizer" = None,
285+
scheduler: Union["DDIMScheduler", "PNDMScheduler", "LMSDiscreteScheduler"] = None,
286+
feature_extractor: Optional["CLIPFeatureExtractor"] = None,
282287
**kwargs,
283288
):
284289
if task is None:
@@ -303,13 +308,7 @@ def _from_transformers(
303308
os.path.join(DIFFUSION_MODEL_VAE_DECODER_SUBFOLDER, ONNX_WEIGHTS_NAME),
304309
]
305310
models_and_onnx_configs = get_stable_diffusion_models_for_export(model)
306-
307311
model.save_config(save_dir_path)
308-
model.tokenizer.save_pretrained(save_dir_path.joinpath("tokenizer"))
309-
model.scheduler.save_pretrained(save_dir_path.joinpath("scheduler"))
310-
if model.feature_extractor is not None:
311-
model.feature_extractor.save_pretrained(save_dir_path.joinpath("feature_extractor"))
312-
313312
export_models(
314313
models_and_onnx_configs=models_and_onnx_configs,
315314
output_dir=save_dir_path,
@@ -325,7 +324,10 @@ def _from_transformers(
325324
force_download=force_download,
326325
cache_dir=cache_dir,
327326
local_files_only=local_files_only,
328-
model_save_dir=save_dir, # important
327+
model_save_dir=save_dir,
328+
tokenizer=tokenizer or model.tokenizer,
329+
scheduler=scheduler or model.scheduler,
330+
feature_extractor=feature_extractor or model.feature_extractor,
329331
**kwargs,
330332
)
331333

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
"neural-compressor>=2.0.0",
3030
"onnx",
3131
"onnxruntime",
32-
"torch<2.0.0", # remove after neural-compressor next release
32+
"torch<2.0.0", # remove after neural-compressor next release
3333
"intel-extension-for-pytorch<2.0.0",
3434
],
3535
"openvino": [
3636
"openvino>=2023.0.0.dev20230217",
3737
"onnx",
3838
"onnxruntime",
39-
"torch<2.0.0", # remove after optimum next release
39+
"torch<2.0.0", # remove after optimum next release
4040
],
4141
"nncf": ["nncf>=2.4.0", "openvino-dev>=2023.0.0.dev20230217"],
4242
"ipex": ["intel-extension-for-pytorch"],

tests/openvino/test_modeling.py

+15-14
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def __init__(self, *args, **kwargs):
114114
super().__init__(*args, **kwargs)
115115
self.OV_MODEL_ID = "echarlaix/distilbert-base-uncased-finetuned-sst-2-english-openvino"
116116
self.OV_SEQ2SEQ_MODEL_ID = "echarlaix/t5-small-openvino"
117-
self.OV_STABLE_DIFFUSION_MODEL_ID = "hf-internal-testing/tiny-stable-diffusion-openvino"
117+
self.OV_DIFFUSION_MODEL_ID = "hf-internal-testing/tiny-stable-diffusion-openvino"
118118

119119
def test_load_from_hub_and_save_model(self):
120120
tokenizer = AutoTokenizer.from_pretrained(self.OV_MODEL_ID)
@@ -152,8 +152,9 @@ def test_load_from_hub_and_save_seq2seq_model(self):
152152
outputs = model.generate(**tokens)
153153
self.assertTrue(torch.equal(loaded_model_outputs, outputs))
154154

155+
@require_diffusers
155156
def test_load_from_hub_and_save_stable_diffusion_model(self):
156-
loaded_pipeline = OVStableDiffusionPipeline.from_pretrained(self.OV_STABLE_DIFFUSION_MODEL_ID, compile=False)
157+
loaded_pipeline = OVStableDiffusionPipeline.from_pretrained(self.OV_DIFFUSION_MODEL_ID, compile=False)
157158
self.assertIsInstance(loaded_pipeline.config, Dict)
158159
prompt = "sailing ship in storm by Leonardo da Vinci"
159160
height = 16
@@ -704,23 +705,23 @@ def test_compare_to_diffusers(self, model_arch: str):
704705
@parameterized.expand(SUPPORTED_ARCHITECTURES)
705706
@require_diffusers
706707
def test_num_images_per_prompt(self, model_arch: str):
708+
from diffusers import DPMSolverMultistepScheduler
709+
707710
model_id = MODEL_NAMES[model_arch]
708-
num_images_per_prompt = 4
709-
batch_size = 6
710-
pipeline = OVStableDiffusionPipeline.from_pretrained(model_id, export=True)
711+
scheduler = DPMSolverMultistepScheduler.from_pretrained(model_id, subfolder="scheduler")
712+
pipeline = OVStableDiffusionPipeline.from_pretrained(model_id, export=True, scheduler=scheduler)
711713
prompt = "sailing ship in storm by Leonardo da Vinci"
712-
outputs = pipeline(prompt, num_inference_steps=2, output_type="np").images
713-
self.assertEqual(outputs.shape, (1, 128, 128, 3))
714-
outputs = pipeline(
715-
prompt, num_inference_steps=2, num_images_per_prompt=num_images_per_prompt, output_type="np"
716-
).images
717-
self.assertEqual(outputs.shape, (num_images_per_prompt, 128, 128, 3))
718-
outputs = pipeline([prompt] * batch_size, num_inference_steps=2, output_type="np").images
719-
self.assertEqual(outputs.shape, (batch_size, 128, 128, 3))
714+
715+
for batch_size in [1, 3]:
716+
for num_images in [1, 2]:
717+
outputs = pipeline(
718+
[prompt] * batch_size, num_inference_steps=2, num_images_per_prompt=num_images, output_type="np"
719+
)
720+
self.assertEqual(outputs.images.shape, (batch_size * num_images, 128, 128, 3))
720721

721722
@parameterized.expand(SUPPORTED_ARCHITECTURES)
722723
@require_diffusers
723-
def test_num_images_per_prompt(self, model_arch: str):
724+
def test_num_images_per_prompt_static_model(self, model_arch: str):
724725
model_id = MODEL_NAMES[model_arch]
725726
batch_size = 3
726727
num_images_per_prompt = 4

0 commit comments

Comments
 (0)