diff --git a/tests/entrypoints/openai_api/test_image_server.py b/tests/entrypoints/openai_api/test_image_server.py index d108b9323..bf3d8bd61 100644 --- a/tests/entrypoints/openai_api/test_image_server.py +++ b/tests/entrypoints/openai_api/test_image_server.py @@ -11,10 +11,11 @@ import base64 import io import json from argparse import Namespace +from http import HTTPStatus from types import SimpleNamespace import pytest -from fastapi import FastAPI +from fastapi import FastAPI, HTTPException from fastapi.testclient import TestClient from PIL import Image from pytest_mock import MockerFixture @@ -23,7 +24,7 @@ from vllm.entrypoints.openai.models.protocol import BaseModelPath from vllm.sampling_params import RequestOutputKind from vllm_omni.entrypoints.async_omni import AsyncOmni -from vllm_omni.entrypoints.openai.api_server import _DiffusionServingModels, router +from vllm_omni.entrypoints.openai.api_server import _check_max_generated_image_size, _DiffusionServingModels, router from vllm_omni.entrypoints.openai.image_api_utils import ( encode_image_base64, parse_size, @@ -1979,6 +1980,56 @@ def test_extract_images_from_result(): assert images[0].size == (32, 32) +# --------------------------------------------------------------------------- +# _check_max_generated_image_size unit tests +# --------------------------------------------------------------------------- + + +def test_width_height_within_limit_passes(): + args = SimpleNamespace(max_generated_image_size=1024 * 1024) + # Exactly at limit is allowed (> not >=) + _check_max_generated_image_size(args, 1024, 1024) + # Below limit + _check_max_generated_image_size(args, 512, 512) + + +def test_width_height_exceeds_limit_raises_400(): + limit = 1024 * 1024 + args = SimpleNamespace(max_generated_image_size=limit) + with pytest.raises(HTTPException) as exc_info: + _check_max_generated_image_size(args, 1025, 1024) + assert exc_info.value.status_code == HTTPStatus.BAD_REQUEST.value + assert "1025x1024" in exc_info.value.detail + assert str(limit) in exc_info.value.detail + + +def test_width_height_error_message_contains_size_hint(): + args = SimpleNamespace(max_generated_image_size=512 * 512) + with pytest.raises(HTTPException) as exc_info: + _check_max_generated_image_size(args, 1024, 512) + assert "--max-generated-image-size" in exc_info.value.detail + + +def test_resolution_within_limit_passes(): + args = SimpleNamespace(max_generated_image_size=1024 * 1024) + # Exactly at limit is allowed (> not >=): 1024*1024 == limit + _check_max_generated_image_size(args, None, None, resolution=1024) + # Below limit + _check_max_generated_image_size(args, None, None, resolution=512) + + +def test_resolution_exceeds_limit_raises_400(): + limit = 1024 * 1024 + args = SimpleNamespace(max_generated_image_size=limit) + with pytest.raises(HTTPException) as exc_info: + _check_max_generated_image_size(args, None, None, resolution=1025) + assert exc_info.value.status_code == HTTPStatus.BAD_REQUEST.value + detail = exc_info.value.detail + assert "1025" in detail + assert "1025x1025" in detail + assert str(limit) in detail + + def test_image_edits_size_auto_preserves_bridge_size(async_omni_stage_configs_only_client): """size=auto must NOT pin the diffusion stage sampling_params.height/width. diff --git a/vllm_omni/entrypoints/cli/serve.py b/vllm_omni/entrypoints/cli/serve.py index 5b6c7d9b3..9468a632f 100644 --- a/vllm_omni/entrypoints/cli/serve.py +++ b/vllm_omni/entrypoints/cli/serve.py @@ -638,8 +638,9 @@ class OmniServeCommand(CLISubcommand): # Diffusion model mixed precision omni_config_group.add_argument( "--max-generated-image-size", + default=7680 * 4320, # 8K resolution type=int, - help="The max size of generate image (height * width).", + help="Maximum generated image size in pixels (height * width).", ) # TTS-specific parameters diff --git a/vllm_omni/entrypoints/openai/api_server.py b/vllm_omni/entrypoints/openai/api_server.py index 36c8201e0..f70a439f5 100755 --- a/vllm_omni/entrypoints/openai/api_server.py +++ b/vllm_omni/entrypoints/openai/api_server.py @@ -2333,7 +2333,8 @@ def _check_max_generated_image_size( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST.value, detail=f"Requested image size {width}x{height} exceeds the maximum allowed " - f"size of {max_generated_image_size} pixels.", + f"size of {max_generated_image_size} pixels. You can reduce the requested size " + f"or increase the server's --max-generated-image-size limit.", ) elif resolution is not None: # When resolution is set, the output size is resolution * resolution @@ -2341,7 +2342,8 @@ def _check_max_generated_image_size( raise HTTPException( status_code=HTTPStatus.BAD_REQUEST.value, detail=f"Requested resolution {resolution} (max {resolution}x{resolution} pixels) " - f"exceeds the maximum allowed size of {max_generated_image_size} pixels.", + f"exceeds the maximum allowed size of {max_generated_image_size} pixels. " + f"You can reduce the requested size or increase the server's --max-generated-image-size limit.", )