Add match_target_res for Qwen Image 2.1 so reference images are scaled to the target's pixel area with their own aspect ratio, consistently across text-embedding caching, training, and sampling, and key the embedding cache on it.
This commit is contained in:
1 parent
71bc877833
commit
07abdbedc7
8 files changed
+113
-35
No files matched your search
@@ -530,6 +530,7 @@ class AiToolkitDataset(LatentCachingMixin, ControlCachingMixin, CLIPCachingMixin
|
||||
encode_first_frame_in_text_embeddings=getattr(self.sd, 'encode_first_frame_in_text_embeddings', False) if self.sd else False,
|
||||
dopsd_self_ref=getattr(self.sd, 'dopsd_self_ref', False) if self.sd else False,
|
||||
text_embedding_space_version=text_embedding_space_version,
|
||||
text_embedding_uses_target_size=getattr(self.sd, 'text_embedding_uses_target_size', False) if self.sd else False,
|
||||
te_padding_side=self.sd.te_padding_side if self.sd else "right",
|
||||
latent_space_version=latent_space_version,
|
||||
temporal_compression=temporal_compression,
|
||||
|
||||
@@ -91,6 +91,8 @@ class FileItemDTO(
|
||||
self.te_padding_side = kwargs.get("te_padding_side", "right")
|
||||
self.latent_space_version = kwargs.get("latent_space_version", "sd1")
|
||||
self.text_embedding_space_version = kwargs.get("text_embedding_space_version", "sd1")
|
||||
# model sizes references against the item's bucket, so the cache key must carry it
|
||||
self.text_embedding_uses_target_size = kwargs.get("text_embedding_uses_target_size", False)
|
||||
if dataset_root is not None:
|
||||
# remove dataset root from path
|
||||
file_key = self.path.replace(dataset_root, "")
|
||||
|
||||
@@ -2250,6 +2250,8 @@ class TextEmbeddingFileItemDTOMixin:
|
||||
# if we have a control image, cache the path
|
||||
if self.encode_control_in_text_embeddings and self.control_path is not None:
|
||||
item["control_path"] = self.control_path
|
||||
if getattr(self, 'text_embedding_uses_target_size', False) and getattr(self, 'crop_width', None):
|
||||
item["control_target_size"] = [self.crop_width, self.crop_height]
|
||||
if self.encode_control_in_text_embeddings and getattr(self, 'control_video_paths', None):
|
||||
item["control_videos"] = sorted(self.control_video_paths)
|
||||
# v2: reference-video vision blocks are no longer resampled by the
|
||||
@@ -2506,6 +2508,10 @@ class TextEmbeddingCachingMixin:
|
||||
ctrl_img = ctrl_img_list[0]
|
||||
else:
|
||||
ctrl_img = ctrl_img_list
|
||||
# the bucket the item trains at, so references can be sized against it
|
||||
target_size = None
|
||||
if getattr(file_item, 'crop_width', None) and getattr(file_item, 'crop_height', None):
|
||||
target_size = (file_item.crop_width, file_item.crop_height)
|
||||
for path, caption in encode_targets:
|
||||
if path in dropout_target_paths:
|
||||
# dropout embeds are plain text. Only fall back to the
|
||||
@@ -2513,9 +2519,11 @@ class TextEmbeddingCachingMixin:
|
||||
try:
|
||||
prompt_embeds: PromptEmbeds = self.sd.encode_prompt(caption)
|
||||
except Exception:
|
||||
prompt_embeds: PromptEmbeds = self.sd.encode_prompt(caption, control_images=ctrl_img)
|
||||
prompt_embeds: PromptEmbeds = self.sd.encode_prompt(
|
||||
caption, control_images=ctrl_img, target_size=target_size)
|
||||
else:
|
||||
prompt_embeds: PromptEmbeds = self.sd.encode_prompt(caption, control_images=ctrl_img)
|
||||
prompt_embeds: PromptEmbeds = self.sd.encode_prompt(
|
||||
caption, control_images=ctrl_img, target_size=target_size)
|
||||
prompt_embeds.save(path)
|
||||
del prompt_embeds
|
||||
elif (
|
||||
|
||||
@@ -681,19 +681,21 @@ class BaseModel:
|
||||
if isinstance(self.adapter, CustomAdapter):
|
||||
self.adapter.is_unconditional_run = False
|
||||
conditional_embeds = self.encode_prompt(
|
||||
gen_config.prompt,
|
||||
gen_config.prompt_2,
|
||||
gen_config.prompt,
|
||||
gen_config.prompt_2,
|
||||
force_all=True,
|
||||
control_images=ctrl_img
|
||||
control_images=ctrl_img,
|
||||
target_size=(gen_config.width, gen_config.height),
|
||||
)
|
||||
|
||||
if isinstance(self.adapter, CustomAdapter):
|
||||
self.adapter.is_unconditional_run = True
|
||||
unconditional_embeds = self.encode_prompt(
|
||||
gen_config.negative_prompt,
|
||||
gen_config.negative_prompt_2,
|
||||
gen_config.negative_prompt,
|
||||
gen_config.negative_prompt_2,
|
||||
force_all=True,
|
||||
control_images=ctrl_img
|
||||
control_images=ctrl_img,
|
||||
target_size=(gen_config.width, gen_config.height),
|
||||
)
|
||||
if isinstance(self.adapter, CustomAdapter):
|
||||
self.adapter.is_unconditional_run = False
|
||||
@@ -1183,6 +1185,7 @@ class BaseModel:
|
||||
max_length=None,
|
||||
dropout_prob=0.0,
|
||||
control_images=None,
|
||||
target_size=None,
|
||||
) -> PromptEmbeds:
|
||||
# sd1.5 embeddings are (bs, 77, 768)
|
||||
prompt = prompt
|
||||
@@ -1194,7 +1197,11 @@ class BaseModel:
|
||||
prompt2 = [prompt2]
|
||||
# if control_images in the signature, pass it. This keep from breaking plugins
|
||||
if self.encode_control_in_text_embeddings:
|
||||
return self.get_prompt_embeds(prompt, control_images=control_images)
|
||||
kwargs = {"control_images": control_images}
|
||||
# target (width, height) only for models that size references against it
|
||||
if target_size is not None and "target_size" in inspect.signature(self.get_prompt_embeds).parameters:
|
||||
kwargs["target_size"] = target_size
|
||||
return self.get_prompt_embeds(prompt, **kwargs)
|
||||
|
||||
return self.get_prompt_embeds(prompt)
|
||||
|
||||
|
||||
@@ -2485,6 +2485,7 @@ class StableDiffusion:
|
||||
max_length=None,
|
||||
dropout_prob=0.0,
|
||||
control_images=None,
|
||||
target_size=None, # accepted for parity with BaseModel; legacy archs ignore it
|
||||
) -> PromptEmbeds:
|
||||
# sd1.5 embeddings are (bs, 77, 768)
|
||||
prompt = prompt
|
||||
|
||||
Reference in new issue
Block a user