[Bugfix] diffusion end points allow model mismatch (#2805)
Signed-off-by: xiaohajiayou <923390377@qq.com> Signed-off-by: Samit <285365963@qq.com> Co-authored-by: Samit <285365963@qq.com> Co-authored-by: SYLAR <125541396+lishunyang12@users.noreply.github.com>
This commit is contained in:
3 files changed
+51
-10
No files matched your search
@@ -851,6 +851,19 @@ def test_model_field_omitted_works(test_client):
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_images_rejects_model_mismatch(test_client):
|
||||||
|
response = test_client.post(
|
||||||
|
"/v1/images/generations",
|
||||||
|
json={
|
||||||
|
"prompt": "test",
|
||||||
|
"model": "Qwen/Qwen-Image-2512",
|
||||||
|
"size": "1024x1024",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert "model mismatch" in response.json()["detail"].lower()
|
||||||
|
|
||||||
|
|
||||||
def make_test_image_bytes(size=(64, 64)) -> bytes:
|
def make_test_image_bytes(size=(64, 64)) -> bytes:
|
||||||
img = Image.new(
|
img = Image.new(
|
||||||
"RGB",
|
"RGB",
|
||||||
@@ -954,6 +967,20 @@ def test_image_edit_rejects_multiple_images_when_model_does_not_support_them(asy
|
|||||||
assert engine.captured_prompt is None
|
assert engine.captured_prompt is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_image_edit_rejects_model_mismatch(test_client):
|
||||||
|
img_bytes = make_test_image_bytes((16, 16))
|
||||||
|
response = test_client.post(
|
||||||
|
"/v1/images/edits",
|
||||||
|
files=[("image", img_bytes)],
|
||||||
|
data={
|
||||||
|
"prompt": "edit me",
|
||||||
|
"model": "Qwen/Qwen-Image-Edit",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert "model mismatch" in response.json()["detail"].lower()
|
||||||
|
|
||||||
|
|
||||||
def test_image_edit_rejects_too_many_images_for_qwen_image_edit_2511(async_omni_test_client):
|
def test_image_edit_rejects_too_many_images_for_qwen_image_edit_2511(async_omni_test_client):
|
||||||
engine = async_omni_test_client.app.state.engine_client
|
engine = async_omni_test_client.app.state.engine_client
|
||||||
engine.get_diffusion_od_config = lambda: SimpleNamespace(
|
engine.get_diffusion_od_config = lambda: SimpleNamespace(
|
||||||
|
|||||||
@@ -564,6 +564,18 @@ def test_missing_prompt_returns_422(test_client):
|
|||||||
assert response.status_code == 422
|
assert response.status_code == 422
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_generation_rejects_model_mismatch(test_client):
|
||||||
|
response = test_client.post(
|
||||||
|
"/v1/videos",
|
||||||
|
data={
|
||||||
|
"prompt": "bad model",
|
||||||
|
"model": "Wan-AI/Wan2.1-T2V-14B-Diffusers",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert "model mismatch" in response.json()["detail"].lower()
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_size_parse_returns_422(test_client):
|
def test_invalid_size_parse_returns_422(test_client):
|
||||||
response = test_client.post(
|
response = test_client.post(
|
||||||
"/v1/videos",
|
"/v1/videos",
|
||||||
|
|||||||
@@ -1321,11 +1321,10 @@ async def generate_images(request: ImageGenerationRequest, raw_request: Request)
|
|||||||
# Get engine client (AsyncOmni) from app state
|
# Get engine client (AsyncOmni) from app state
|
||||||
engine_client, model_name, stage_configs = _get_engine_and_model(raw_request)
|
engine_client, model_name, stage_configs = _get_engine_and_model(raw_request)
|
||||||
|
|
||||||
# Validate model field (warn if mismatch, don't error)
|
|
||||||
if request.model is not None and request.model != model_name:
|
if request.model is not None and request.model != model_name:
|
||||||
logger.warning(
|
raise HTTPException(
|
||||||
f"Model mismatch: request specifies '{request.model}' but "
|
status_code=HTTPStatus.BAD_REQUEST.value,
|
||||||
f"server is running '{model_name}'. Using server model."
|
detail=(f"Model mismatch: request specifies '{request.model}' but server is running '{model_name}'."),
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -1517,8 +1516,9 @@ async def edit_images(
|
|||||||
# 1. get engine and model
|
# 1. get engine and model
|
||||||
engine_client, model_name, stage_configs = _get_engine_and_model(raw_request)
|
engine_client, model_name, stage_configs = _get_engine_and_model(raw_request)
|
||||||
if model is not None and model != model_name:
|
if model is not None and model != model_name:
|
||||||
logger.warning(
|
raise HTTPException(
|
||||||
f"Model mismatch: request specifies '{model}' but server is running '{model_name}'. Using server model."
|
status_code=HTTPStatus.BAD_REQUEST.value,
|
||||||
|
detail=(f"Model mismatch: request specifies '{model}' but server is running '{model_name}'."),
|
||||||
)
|
)
|
||||||
# 2. get output format & compression
|
# 2. get output format & compression
|
||||||
output_format = _choose_output_format(output_format, background)
|
output_format = _choose_output_format(output_format, background)
|
||||||
@@ -2234,10 +2234,12 @@ async def _parse_video_form(
|
|||||||
app_model_name, app_stage_configs = _resolve_video_runtime_context(raw_request)
|
app_model_name, app_stage_configs = _resolve_video_runtime_context(raw_request)
|
||||||
effective_model_name = handler.model_name or app_model_name or request.model or "unknown"
|
effective_model_name = handler.model_name or app_model_name or request.model or "unknown"
|
||||||
if request.model is not None and effective_model_name is not None and request.model != effective_model_name:
|
if request.model is not None and effective_model_name is not None and request.model != effective_model_name:
|
||||||
logger.warning(
|
raise HTTPException(
|
||||||
"Model mismatch: request specifies '%s' but server is running '%s'. Using server model.",
|
status_code=HTTPStatus.BAD_REQUEST.value,
|
||||||
request.model,
|
detail=(
|
||||||
effective_model_name,
|
f"Model mismatch: request specifies '{request.model}' but server is running "
|
||||||
|
f"'{effective_model_name}'."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
handler.set_stage_configs_if_missing(app_stage_configs)
|
handler.set_stage_configs_if_missing(app_stage_configs)
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
|
|||||||
Reference in new issue
Block a user