Files
vllm-omni/tests/diffusion/models/sd3/test_sd3_pipeline.py
T

156 lines
5.3 KiB
Python

from types import SimpleNamespace
import pytest
import torch
from torch import nn
from vllm_omni.diffusion.models.sd3.pipeline_sd3 import StableDiffusion3Pipeline
from vllm_omni.diffusion.worker.request_batch import DiffusionRequestBatch
pytestmark = [pytest.mark.core_model, pytest.mark.cpu]
def _make_sd3_sampling(**overrides):
values = {
"height": 32,
"width": 32,
"num_inference_steps": 2,
"sigmas": None,
"max_sequence_length": None,
"num_outputs_per_prompt": 0,
"generator": None,
"latents": None,
"guidance_scale": 4.0,
"output_type": None,
}
values.update(overrides)
return SimpleNamespace(**values)
def _make_sd3_pipeline():
pipeline = object.__new__(StableDiffusion3Pipeline)
nn.Module.__init__(pipeline)
pipeline.vae_scale_factor = 8
pipeline.patch_size = 2
pipeline.default_sample_size = 128
pipeline.transformer = SimpleNamespace(in_channels=1)
return pipeline
def test_forward_collates_request_prompt_tensors_for_sd3():
pipeline = _make_sd3_pipeline()
class StopAfterDiffuseError(Exception):
pass
encode_calls = []
diffuse_call = {}
def _fake_encode_prompt(**kwargs):
encode_calls.append(kwargs)
prompt_embeds = kwargs["prompt_embeds"]
if prompt_embeds is None:
prompt_embeds = torch.empty(2, 2, 3)
return prompt_embeds, kwargs.get("pooled_prompt_embeds")
def _fake_diffuse(**kwargs):
diffuse_call.update(kwargs)
raise StopAfterDiffuseError
pipeline.encode_prompt = _fake_encode_prompt
pipeline.prepare_latents = lambda *args, **kwargs: torch.zeros(2, 1, 1, 1)
pipeline.prepare_timesteps = lambda *args, **kwargs: (torch.tensor([1.0]), 1)
pipeline.diffuse = _fake_diffuse
prompt_embeds_a = torch.zeros(2, 3)
prompt_embeds_b = torch.ones(2, 3)
pooled_prompt_embeds_a = torch.full((4,), 2.0)
pooled_prompt_embeds_b = torch.full((4,), 3.0)
negative_prompt_embeds_a = torch.full((2, 3), 4.0)
negative_prompt_embeds_b = torch.full((2, 3), 5.0)
negative_pooled_prompt_embeds_a = torch.full((4,), 6.0)
negative_pooled_prompt_embeds_b = torch.full((4,), 7.0)
batch = DiffusionRequestBatch(
requests=[
SimpleNamespace(
request_id="sd3-prompt-a",
prompt={
"prompt": "prompt-a",
"negative_prompt": "negative-a",
"prompt_embeds": prompt_embeds_a,
"pooled_prompt_embeds": pooled_prompt_embeds_a,
"negative_prompt_embeds": negative_prompt_embeds_a,
"negative_pooled_prompt_embeds": negative_pooled_prompt_embeds_a,
},
sampling_params=_make_sd3_sampling(),
),
SimpleNamespace(
request_id="sd3-prompt-b",
prompt={
"prompt": "prompt-b",
"negative_prompt": "negative-b",
"additional_information": {
"prompt_embeds": [prompt_embeds_b],
"pooled_prompt_embeds": [pooled_prompt_embeds_b],
"negative_prompt_embeds": [negative_prompt_embeds_b],
"negative_pooled_prompt_embeds": [negative_pooled_prompt_embeds_b],
},
},
sampling_params=_make_sd3_sampling(),
),
]
)
with pytest.raises(StopAfterDiffuseError):
pipeline.forward(batch)
assert encode_calls[0]["prompt"] is None
assert encode_calls[0]["prompt_2"] is None
assert encode_calls[0]["prompt_3"] is None
torch.testing.assert_close(
encode_calls[0]["prompt_embeds"],
torch.stack([prompt_embeds_a, prompt_embeds_b], dim=0),
)
torch.testing.assert_close(
encode_calls[0]["pooled_prompt_embeds"],
torch.stack([pooled_prompt_embeds_a, pooled_prompt_embeds_b], dim=0),
)
assert encode_calls[1]["prompt"] is None
assert encode_calls[1]["prompt_2"] is None
assert encode_calls[1]["prompt_3"] is None
torch.testing.assert_close(
encode_calls[1]["prompt_embeds"],
torch.stack([negative_prompt_embeds_a, negative_prompt_embeds_b], dim=0),
)
torch.testing.assert_close(
encode_calls[1]["pooled_prompt_embeds"],
torch.stack([negative_pooled_prompt_embeds_a, negative_pooled_prompt_embeds_b], dim=0),
)
torch.testing.assert_close(
diffuse_call["pooled_prompt_embeds"],
torch.stack([pooled_prompt_embeds_a, pooled_prompt_embeds_b], dim=0),
)
torch.testing.assert_close(
diffuse_call["negative_pooled_prompt_embeds"],
torch.stack([negative_pooled_prompt_embeds_a, negative_pooled_prompt_embeds_b], dim=0),
)
def test_encode_prompt_preserves_direct_pooled_prompt_embeds():
pipeline = _make_sd3_pipeline()
prompt_embeds = torch.zeros(1, 2, 3)
pooled_prompt_embeds = torch.ones(1, 4)
actual_prompt_embeds, actual_pooled_prompt_embeds = pipeline.encode_prompt(
prompt=None,
prompt_2=None,
prompt_3=None,
prompt_embeds=prompt_embeds,
pooled_prompt_embeds=pooled_prompt_embeds,
)
assert actual_prompt_embeds is prompt_embeds
assert actual_pooled_prompt_embeds is pooled_prompt_embeds