[Bugfix] Fix Qwen-Image min-size normalization for tiny requests (#2637)
Signed-off-by: David Chen <530634352@qq.com>
This commit is contained in:
1 parent
956f53b278
commit
85d63c47f9
6 files changed
+65
-18
No files matched your search
@@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
|
||||
from vllm_omni.diffusion.utils.size_utils import (
|
||||
normalize_min_aligned_size,
|
||||
)
|
||||
|
||||
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("height", "width", "expected"),
|
||||
[
|
||||
(1, 1, (16, 16)),
|
||||
(15, 15, (16, 16)),
|
||||
(17, 17, (16, 16)),
|
||||
(31, 33, (16, 32)),
|
||||
(64, 80, (64, 80)),
|
||||
],
|
||||
)
|
||||
def test_normalize_min_aligned_size_clamps_to_minimum_aligned_shape(height, width, expected):
|
||||
assert normalize_min_aligned_size(height, width, alignment=16) == expected
|
||||
|
||||
|
||||
def test_normalize_min_aligned_size_rejects_invalid_alignment():
|
||||
with pytest.raises(ValueError, match="positive alignment"):
|
||||
normalize_min_aligned_size(16, 16, alignment=0)
|
||||
@@ -34,6 +34,9 @@ from vllm_omni.diffusion.models.qwen_image.qwen_image_transformer import (
|
||||
)
|
||||
from vllm_omni.diffusion.profiler.diffusion_pipeline_profiler import DiffusionPipelineProfilerMixin
|
||||
from vllm_omni.diffusion.request import OmniDiffusionRequest
|
||||
from vllm_omni.diffusion.utils.size_utils import (
|
||||
normalize_min_aligned_size,
|
||||
)
|
||||
from vllm_omni.diffusion.utils.tf_utils import get_transformer_config_kwargs
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -938,6 +941,7 @@ class QwenImagePipeline(nn.Module, QwenImageCFGParallelMixin, DiffusionPipelineP
|
||||
|
||||
height = req.sampling_params.height or self.default_sample_size * self.vae_scale_factor
|
||||
width = req.sampling_params.width or self.default_sample_size * self.vae_scale_factor
|
||||
height, width = normalize_min_aligned_size(height, width, self.vae_scale_factor * 2)
|
||||
num_inference_steps = req.sampling_params.num_inference_steps or num_inference_steps
|
||||
sigmas = req.sampling_params.sigmas or sigmas
|
||||
max_sequence_length = req.sampling_params.max_sequence_length or max_sequence_length
|
||||
|
||||
@@ -37,6 +37,9 @@ from vllm_omni.diffusion.models.qwen_image.qwen_image_transformer import (
|
||||
)
|
||||
from vllm_omni.diffusion.profiler.diffusion_pipeline_profiler import DiffusionPipelineProfilerMixin
|
||||
from vllm_omni.diffusion.request import OmniDiffusionRequest
|
||||
from vllm_omni.diffusion.utils.size_utils import (
|
||||
normalize_min_aligned_size,
|
||||
)
|
||||
from vllm_omni.diffusion.utils.tf_utils import get_transformer_config_kwargs
|
||||
from vllm_omni.inputs.data import OmniTextPrompt
|
||||
from vllm_omni.model_executor.model_loader.weight_utils import (
|
||||
@@ -97,9 +100,7 @@ def get_qwen_image_edit_pre_process_func(
|
||||
width = request.sampling_params.width or calculated_width
|
||||
|
||||
# Ensure dimensions are multiples of vae_scale_factor * 2
|
||||
multiple_of = vae_scale_factor * 2
|
||||
height = height // multiple_of * multiple_of
|
||||
width = width // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, vae_scale_factor * 2)
|
||||
|
||||
# Store calculated dimensions in request
|
||||
prompt["additional_information"]["calculated_height"] = calculated_height
|
||||
@@ -661,9 +662,7 @@ class QwenImageEditPipeline(nn.Module, SupportImageInput, QwenImageCFGParallelMi
|
||||
height = height or calculated_height
|
||||
width = width or calculated_width
|
||||
|
||||
multiple_of = self.vae_scale_factor * 2
|
||||
width = width // multiple_of * multiple_of
|
||||
height = height // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, self.vae_scale_factor * 2)
|
||||
|
||||
if image is not None and not (isinstance(image, torch.Tensor) and image.size(1) == self.latent_channels):
|
||||
image = self.image_processor.resize(image, calculated_height, calculated_width)
|
||||
|
||||
@@ -40,6 +40,9 @@ from vllm_omni.diffusion.models.qwen_image.qwen_image_transformer import (
|
||||
)
|
||||
from vllm_omni.diffusion.profiler.diffusion_pipeline_profiler import DiffusionPipelineProfilerMixin
|
||||
from vllm_omni.diffusion.request import OmniDiffusionRequest
|
||||
from vllm_omni.diffusion.utils.size_utils import (
|
||||
normalize_min_aligned_size,
|
||||
)
|
||||
from vllm_omni.diffusion.utils.tf_utils import get_transformer_config_kwargs
|
||||
from vllm_omni.inputs.data import OmniTextPrompt
|
||||
from vllm_omni.model_executor.model_loader.weight_utils import (
|
||||
@@ -99,9 +102,7 @@ def get_qwen_image_edit_plus_pre_process_func(
|
||||
width = request.sampling_params.width or calculated_width
|
||||
|
||||
# Ensure dimensions are multiples of vae_scale_factor * 2
|
||||
multiple_of = vae_scale_factor * 2
|
||||
height = height // multiple_of * multiple_of
|
||||
width = width // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, vae_scale_factor * 2)
|
||||
|
||||
# Store calculated dimensions in request
|
||||
prompt["additional_information"]["calculated_height"] = calculated_height
|
||||
@@ -604,9 +605,7 @@ class QwenImageEditPlusPipeline(
|
||||
height = height or calculated_height
|
||||
width = width or calculated_width
|
||||
|
||||
multiple_of = self.vae_scale_factor * 2
|
||||
width = width // multiple_of * multiple_of
|
||||
height = height // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, self.vae_scale_factor * 2)
|
||||
|
||||
condition_images = []
|
||||
vae_images = []
|
||||
|
||||
@@ -36,6 +36,9 @@ from vllm_omni.diffusion.models.qwen_image.qwen_image_transformer import (
|
||||
)
|
||||
from vllm_omni.diffusion.profiler.diffusion_pipeline_profiler import DiffusionPipelineProfilerMixin
|
||||
from vllm_omni.diffusion.request import OmniDiffusionRequest
|
||||
from vllm_omni.diffusion.utils.size_utils import (
|
||||
normalize_min_aligned_size,
|
||||
)
|
||||
from vllm_omni.diffusion.utils.tf_utils import get_transformer_config_kwargs
|
||||
from vllm_omni.inputs.data import OmniTextPrompt
|
||||
from vllm_omni.model_executor.model_loader.weight_utils import (
|
||||
@@ -109,9 +112,7 @@ def get_qwen_image_layered_pre_process_func(
|
||||
height = calculated_height
|
||||
width = calculated_width
|
||||
|
||||
multiple_of = vae_scale_factor * 2
|
||||
width = width // multiple_of * multiple_of
|
||||
height = height // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, vae_scale_factor * 2)
|
||||
|
||||
# Store calculated dimensions in request
|
||||
prompt["additional_information"]["calculated_height"] = calculated_height
|
||||
@@ -665,9 +666,7 @@ the image\n<|vision_start|><|image_pad|><|vision_end|><|im_end|>\n<|im_start|>as
|
||||
height = calculated_height
|
||||
width = calculated_width
|
||||
|
||||
multiple_of = self.vae_scale_factor * 2
|
||||
width = width // multiple_of * multiple_of
|
||||
height = height // multiple_of * multiple_of
|
||||
height, width = normalize_min_aligned_size(height, width, self.vae_scale_factor * 2)
|
||||
|
||||
if image is not None and not (isinstance(image, torch.Tensor) and image.size(1) == self.latent_channels):
|
||||
image = self.image_processor.resize(image, calculated_height, calculated_width)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
|
||||
"""Shared size normalization helpers for diffusion pipelines."""
|
||||
|
||||
|
||||
def normalize_min_aligned_size(height: int, width: int, alignment: int) -> tuple[int, int]:
|
||||
"""Clamp dimensions to the minimum valid aligned size.
|
||||
|
||||
This preserves floor-to-alignment behavior for normal requests while
|
||||
preventing very small dimensions from collapsing to zero after alignment.
|
||||
"""
|
||||
|
||||
alignment = int(alignment)
|
||||
if alignment <= 0:
|
||||
raise ValueError(f"Expected positive alignment, got {alignment}")
|
||||
|
||||
normalized_height = max(alignment, (int(height) // alignment) * alignment)
|
||||
normalized_width = max(alignment, (int(width) // alignment) * alignment)
|
||||
return normalized_height, normalized_width
|
||||
Reference in new issue
Block a user