[XPU][HunyuanImage3] Fix HunyuanImage-3.0 text-to-image on XPU (#7674)
Signed-off-by: Joshna Medisetty <joshna.medisetty@intel.com>
This commit is contained in:
1 parent
b81f2c5d4b
commit
77d8de70da
4 files changed
+22
-12
No files matched your search
@@ -106,11 +106,14 @@ platforms:
|
||||
|
||||
xpu:
|
||||
stages:
|
||||
# Both stages stay resident, so they cannot share cards.
|
||||
- stage_id: 0
|
||||
gpu_memory_utilization: 0.95
|
||||
devices: "0,1,2,3,4,5,6,7"
|
||||
tensor_parallel_size: 8
|
||||
max_num_batched_tokens: 32784
|
||||
devices: "0,1,2,3"
|
||||
tensor_parallel_size: 4
|
||||
# fp8 AR weights leave under 1 GiB for KV; 22800 tokens will not fit.
|
||||
max_num_batched_tokens: 8192
|
||||
max_model_len: 8192
|
||||
quantization: fp8
|
||||
enable_expert_parallel: true
|
||||
worker_cls: vllm_omni.platforms.xpu.worker.xpu_ar_worker.XPUARWorker
|
||||
@@ -120,12 +123,12 @@ platforms:
|
||||
repetition_penalty: 1.1
|
||||
- stage_id: 1
|
||||
gpu_memory_utilization: 0.9
|
||||
devices: "0,1,2,3,4,5,6,7"
|
||||
devices: "4,5,6,7"
|
||||
quantization: fp8
|
||||
parallel_config:
|
||||
pipeline_parallel_size: 1
|
||||
data_parallel_size: 1
|
||||
tensor_parallel_size: 8
|
||||
tensor_parallel_size: 4
|
||||
enable_expert_parallel: true
|
||||
sequence_parallel_size: 1
|
||||
ulysses_degree: 1
|
||||
|
||||
@@ -3040,7 +3040,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
|
||||
# 3. negative cfg prefill
|
||||
# For CFG distilled models, skip negative CFG prefill (cfg_factor=1, no negative prompt)
|
||||
if self.do_classifier_free_guidance and not self.model.config.cfg_distilled:
|
||||
if self.do_classifier_free_guidance and not getattr(self.model.config, "cfg_distilled", False):
|
||||
self._maybe_run_negative_cfg_prefill(
|
||||
input_ids=input_ids,
|
||||
model_kwargs=model_kwargs,
|
||||
@@ -3151,7 +3151,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
# For CFG distilled models, skip CFG parallel (cfg_factor=1, no negative branch)
|
||||
cfg_parallel_ready = (
|
||||
self.do_classifier_free_guidance
|
||||
and not self.model.config.cfg_distilled
|
||||
and not getattr(self.model.config, "cfg_distilled", False)
|
||||
and get_classifier_free_guidance_world_size() == 2
|
||||
)
|
||||
|
||||
@@ -3207,7 +3207,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
self._split_model_kwargs_for_cfg_parallel(model_kwargs, batch_size, cfg_rank)
|
||||
else:
|
||||
# For CFG distilled models, cfg_factor is always 1 (CFG embedded in model)
|
||||
if self.model.config.cfg_distilled:
|
||||
if getattr(self.model.config, "cfg_distilled", False):
|
||||
cfg_factor = 1
|
||||
else:
|
||||
cfg_factor = 1 + self.do_classifier_free_guidance
|
||||
@@ -3252,7 +3252,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
# Sequential CFG: double the batch
|
||||
latent_model_input = torch.cat([latents] * cfg_factor)
|
||||
|
||||
if self.model.config.use_meanflow:
|
||||
if getattr(self.model.config, "use_meanflow", False):
|
||||
r = self.scheduler.get_timestep_r(t)
|
||||
r_expand = r.repeat(latent_model_input.shape[0])
|
||||
else:
|
||||
@@ -3281,7 +3281,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
|
||||
if should_compute:
|
||||
# Handle guidance for CFG distilled models
|
||||
if self.model.config.cfg_distilled:
|
||||
if getattr(self.model.config, "cfg_distilled", False):
|
||||
model_kwargs["guidance"] = torch.tensor(
|
||||
[1000.0 * self._guidance_scale],
|
||||
device=self.device,
|
||||
@@ -3308,7 +3308,7 @@ class HunyuanImage3Text2ImagePipeline(DiffusionPipeline):
|
||||
# Perform guidance
|
||||
# For CFG distilled models, guidance is already embedded in the model,
|
||||
# so we skip the explicit CFG computation
|
||||
if self.model.config.cfg_distilled:
|
||||
if getattr(self.model.config, "cfg_distilled", False):
|
||||
# CFG distilled: guidance is handled internally via guidance_emb
|
||||
pass
|
||||
elif cfg_parallel_ready:
|
||||
|
||||
@@ -338,6 +338,9 @@ class HunyuanImage3Pipeline(
|
||||
supports_step_execution: ClassVar[bool] = True
|
||||
supports_request_batch = False
|
||||
support_image_input = True
|
||||
# The warmup request's blank image routes this AR+diffusion model down its
|
||||
# image-edit path, where the token block cannot match the latent patch grid.
|
||||
dummy_run_num_frames: ClassVar[int] = 0
|
||||
_dit_modules: ClassVar[list[str]] = ["model"]
|
||||
_encoder_modules: ClassVar[list[str]] = ["vision_model"]
|
||||
_vae_modules: ClassVar[list[str]] = ["vae"]
|
||||
|
||||
@@ -1557,7 +1557,11 @@ class HunyuanImage3ForConditionalGeneration(nn.Module, SupportsMultiModal, Suppo
|
||||
self._end_ratio_id = tokenizer.convert_tokens_to_ids("<img_ratio_32>")
|
||||
ratio_33 = tokenizer.convert_tokens_to_ids("<img_ratio_33>")
|
||||
ratio_36 = tokenizer.convert_tokens_to_ids("<img_ratio_36>")
|
||||
self._ratio_other_slices = [(ratio_33, ratio_36 + 1)]
|
||||
# The base checkpoint stops at <img_ratio_32>; only Instruct has 33-36.
|
||||
if ratio_33 is None or ratio_36 is None:
|
||||
self._ratio_other_slices = []
|
||||
else:
|
||||
self._ratio_other_slices = [(ratio_33, ratio_36 + 1)]
|
||||
# Build the full set of ratio token IDs for use as stop tokens.
|
||||
self._all_ratio_ids = set(range(self._start_ratio_id, self._end_ratio_id + 1))
|
||||
for s, e in self._ratio_other_slices:
|
||||
|
||||
Reference in new issue
Block a user