mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-21 00:21:49 +00:00
fix(azure-ai): keep FLUX.2 tolerant of OpenAI-only image params
This commit is contained in:
parent
cf08440557
commit
c0b0ba20b2
4 changed files with 67 additions and 29 deletions
|
|
@ -31,22 +31,7 @@ class AzureFoundryFlux2ImageEditConfig(OpenAIImageEditConfig):
|
|||
"""
|
||||
|
||||
def get_supported_openai_params(self, model: str) -> list:
|
||||
"""
|
||||
FLUX 2 supports a subset of OpenAI image edit params
|
||||
"""
|
||||
return [
|
||||
"n",
|
||||
"size",
|
||||
"width",
|
||||
"height",
|
||||
"num_images",
|
||||
"seed",
|
||||
"safety_tolerance",
|
||||
"output_format",
|
||||
"aspect_ratio",
|
||||
"guidance",
|
||||
"steps",
|
||||
]
|
||||
return AzureFoundryFluxImageGenerationConfig().get_supported_openai_params(model)
|
||||
|
||||
def map_openai_params(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,18 @@ from collections.abc import Mapping
|
|||
from types import MappingProxyType
|
||||
from typing import Final
|
||||
|
||||
from litellm.exceptions import BadRequestError, UnsupportedParamsError
|
||||
from litellm.llms.openai.image_generation import GPTImageGenerationConfig
|
||||
from litellm.types.llms.openai import OpenAIImageGenerationOptionalParams
|
||||
|
||||
FLUX2_DROPPED_OPENAI_PARAMS: Final[tuple[OpenAIImageGenerationOptionalParams, ...]] = (
|
||||
"background",
|
||||
"moderation",
|
||||
"output_compression",
|
||||
"quality",
|
||||
"user",
|
||||
)
|
||||
|
||||
|
||||
class AzureFoundryFluxImageGenerationConfig(GPTImageGenerationConfig):
|
||||
"""Azure Foundry BFL API configuration for FLUX image generation."""
|
||||
|
|
@ -81,10 +90,13 @@ class AzureFoundryFluxImageGenerationConfig(GPTImageGenerationConfig):
|
|||
"num_images",
|
||||
"guidance",
|
||||
"steps",
|
||||
*FLUX2_DROPPED_OPENAI_PARAMS,
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _map_parameter(name: str, value: object) -> tuple[tuple[str, object], ...]:
|
||||
def _map_parameter(name: str, value: object, model: str) -> tuple[tuple[str, object], ...]:
|
||||
if name in FLUX2_DROPPED_OPENAI_PARAMS:
|
||||
return ()
|
||||
if isinstance(value, str):
|
||||
if name in ("n", "num_images", "width", "height", "steps", "seed", "safety_tolerance"):
|
||||
return (("num_images" if name == "n" else name, int(value)),)
|
||||
|
|
@ -94,11 +106,17 @@ class AzureFoundryFluxImageGenerationConfig(GPTImageGenerationConfig):
|
|||
return (("num_images", value),)
|
||||
if name != "size":
|
||||
return ((name, value),)
|
||||
if str(value).lower() == "auto":
|
||||
return ()
|
||||
|
||||
try:
|
||||
width, height = (int(dimension) for dimension in str(value).lower().split("x"))
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError(f"Invalid size format '{value}'. Expected 'WxH', for example '1024x1024'.")
|
||||
raise BadRequestError(
|
||||
message=f"Invalid size format '{value}'. Expected 'WxH', for example '1024x1024'.",
|
||||
model=model,
|
||||
llm_provider="azure_ai",
|
||||
)
|
||||
return (("width", width), ("height", height))
|
||||
|
||||
def map_openai_params(
|
||||
|
|
@ -118,9 +136,13 @@ class AzureFoundryFluxImageGenerationConfig(GPTImageGenerationConfig):
|
|||
supported_params: Final = self.get_supported_openai_params(model)
|
||||
unsupported_params: Final = tuple(name for name in non_default_params if name not in supported_params)
|
||||
if unsupported_params and not drop_params:
|
||||
raise ValueError(
|
||||
f"Parameters {unsupported_params} are not supported for model {model}. "
|
||||
f"Supported parameters are {supported_params}. Set drop_params=True to drop unsupported parameters."
|
||||
raise UnsupportedParamsError(
|
||||
message=(
|
||||
f"Parameters {unsupported_params} are not supported for model {model}. "
|
||||
f"Supported parameters are {supported_params}. Set drop_params=True to drop unsupported parameters."
|
||||
),
|
||||
model=model,
|
||||
llm_provider="azure_ai",
|
||||
)
|
||||
|
||||
mapped_params: Final[Mapping[str, object]] = MappingProxyType(
|
||||
|
|
@ -128,7 +150,7 @@ class AzureFoundryFluxImageGenerationConfig(GPTImageGenerationConfig):
|
|||
mapped_name: mapped_value
|
||||
for name, value in non_default_params.items()
|
||||
if name in supported_params
|
||||
for mapped_name, mapped_value in self._map_parameter(name, value)
|
||||
for mapped_name, mapped_value in self._map_parameter(name, value, model)
|
||||
}
|
||||
)
|
||||
return {**optional_params, **mapped_params} # mutable-ok: inherited config contract returns a dict
|
||||
|
|
|
|||
|
|
@ -176,3 +176,14 @@ def test_flux2_image_edit_preserves_controls_and_pixel_cost(dimensions: Mapping[
|
|||
)
|
||||
|
||||
assert response._hidden_params["response_cost"] == pytest.approx(5e-08 * 2048 * 1024 * 2)
|
||||
|
||||
|
||||
def test_flux2_image_edit_accepts_and_drops_openai_only_parameters():
|
||||
optional_params: Final = ImageEditRequestUtils.get_optional_params_image_edit(
|
||||
model="FLUX.2-pro",
|
||||
image_edit_provider_config=AzureFoundryFlux2ImageEditConfig(),
|
||||
image_edit_optional_params={"n": 1, "size": "auto", "quality": "high", "user": "end-user-1"},
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
assert optional_params == {"num_images": 1}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from litellm.llms.azure_ai.image_generation.flux_transformation import (
|
|||
AzureFoundryFluxImageGenerationConfig,
|
||||
)
|
||||
from litellm.types.utils import ImageObject, ImageResponse
|
||||
from litellm.utils import _invalidate_model_cost_lowercase_map
|
||||
from litellm.utils import _invalidate_model_cost_lowercase_map, get_optional_params_image_gen
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
|
@ -86,15 +86,35 @@ def test_flux2_flex_maps_openai_and_provider_parameters():
|
|||
}
|
||||
|
||||
|
||||
def test_flux2_flex_rejects_invalid_size():
|
||||
with pytest.raises(ValueError, match="Expected 'WxH'"):
|
||||
AzureFoundryFluxImageGenerationConfig().map_openai_params(
|
||||
non_default_params={"size": "large"},
|
||||
optional_params={},
|
||||
def test_flux2_flex_rejects_invalid_size_as_bad_request():
|
||||
with pytest.raises(litellm.BadRequestError, match="Expected 'WxH'") as raised:
|
||||
get_optional_params_image_gen(
|
||||
model="FLUX.2-flex",
|
||||
drop_params=False,
|
||||
custom_llm_provider="azure_ai",
|
||||
provider_config=AzureFoundryFluxImageGenerationConfig(),
|
||||
size="large",
|
||||
)
|
||||
|
||||
assert raised.value.status_code == 400
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ("FLUX.2-pro", "FLUX.2-flex"))
|
||||
def test_flux2_accepts_and_drops_openai_only_image_parameters(model: str):
|
||||
optional_params: Final = get_optional_params_image_gen(
|
||||
model=model,
|
||||
custom_llm_provider="azure_ai",
|
||||
provider_config=AzureFoundryFluxImageGenerationConfig(),
|
||||
n=1,
|
||||
size="auto",
|
||||
quality="high",
|
||||
user="end-user-1",
|
||||
background="transparent",
|
||||
moderation="low",
|
||||
output_compression=50,
|
||||
)
|
||||
|
||||
assert optional_params == {"num_images": 1}
|
||||
|
||||
|
||||
def test_flux2_flex_model_info():
|
||||
model_info = litellm.get_model_info(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue