mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
add support for Amazon Nova Canvas model (#7838)
* add initial support for Amazon Nova Canvas model Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * adjust name to AmazonNovaCanvas and map function variables to config Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * tighten model name check Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * fix quality mapping Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * add premium quality in config Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * support all Amazon Nova Canvas tasks * remove unused import Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * add tests for image generation tasks and fix payload Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * add missing util file Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * update model prices backup file Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> * remove image tasks other than text->image Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> --------- Signed-off-by: omrishiv <327609+omrishiv@users.noreply.github.com> Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
This commit is contained in:
parent
0fa3ec98ab
commit
0674491386
8 changed files with 212 additions and 22 deletions
|
|
@ -899,6 +899,7 @@ from .llms.bedrock.chat.invoke_transformations.base_invoke_transformation import
|
|||
|
||||
from .llms.bedrock.image.amazon_stability1_transformation import AmazonStabilityConfig
|
||||
from .llms.bedrock.image.amazon_stability3_transformation import AmazonStability3Config
|
||||
from .llms.bedrock.image.amazon_nova_canvas_transformation import AmazonNovaCanvasConfig
|
||||
from .llms.bedrock.embed.amazon_titan_g1_transformation import AmazonTitanG1Config
|
||||
from .llms.bedrock.embed.amazon_titan_multimodal_transformation import (
|
||||
AmazonTitanMultimodalEmbeddingG1Config,
|
||||
|
|
|
|||
106
litellm/llms/bedrock/image/amazon_nova_canvas_transformation.py
Normal file
106
litellm/llms/bedrock/image/amazon_nova_canvas_transformation.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import types
|
||||
from typing import List, Optional
|
||||
|
||||
from openai.types.image import Image
|
||||
|
||||
from litellm.types.llms.bedrock import (
|
||||
AmazonNovaCanvasTextToImageRequest, AmazonNovaCanvasTextToImageResponse,
|
||||
AmazonNovaCanvasTextToImageParams, AmazonNovaCanvasRequestBase,
|
||||
)
|
||||
from litellm.types.utils import ImageResponse
|
||||
|
||||
|
||||
class AmazonNovaCanvasConfig:
|
||||
"""
|
||||
Reference: https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/model-catalog/serverless/amazon.nova-canvas-v1:0
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def get_config(cls):
|
||||
return {
|
||||
k: v
|
||||
for k, v in cls.__dict__.items()
|
||||
if not k.startswith("__")
|
||||
and not isinstance(
|
||||
v,
|
||||
(
|
||||
types.FunctionType,
|
||||
types.BuiltinFunctionType,
|
||||
classmethod,
|
||||
staticmethod,
|
||||
),
|
||||
)
|
||||
and v is not None
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_supported_openai_params(cls, model: Optional[str] = None) -> List:
|
||||
"""
|
||||
"""
|
||||
return ["n", "size", "quality"]
|
||||
|
||||
@classmethod
|
||||
def _is_nova_model(cls, model: Optional[str] = None) -> bool:
|
||||
"""
|
||||
Returns True if the model is a Nova Canvas model
|
||||
|
||||
Nova models follow this pattern:
|
||||
|
||||
"""
|
||||
if model:
|
||||
if "amazon.nova-canvas" in model:
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def transform_request_body(
|
||||
cls, text: str, optional_params: dict
|
||||
) -> AmazonNovaCanvasRequestBase:
|
||||
"""
|
||||
Transform the request body for Amazon Nova Canvas model
|
||||
"""
|
||||
task_type = optional_params.pop("taskType", "TEXT_IMAGE")
|
||||
image_generation_config = optional_params.pop("imageGenerationConfig", {})
|
||||
image_generation_config = {**image_generation_config, **optional_params}
|
||||
if task_type == "TEXT_IMAGE":
|
||||
text_to_image_params = image_generation_config.pop("textToImageParams", {})
|
||||
text_to_image_params = {"text" :text, **text_to_image_params}
|
||||
text_to_image_params = AmazonNovaCanvasTextToImageParams(**text_to_image_params)
|
||||
return AmazonNovaCanvasTextToImageRequest(textToImageParams=text_to_image_params, taskType=task_type,
|
||||
imageGenerationConfig=image_generation_config)
|
||||
raise NotImplementedError(f"Task type {task_type} is not supported")
|
||||
|
||||
@classmethod
|
||||
def map_openai_params(cls, non_default_params: dict, optional_params: dict) -> dict:
|
||||
"""
|
||||
Map the OpenAI params to the Bedrock params
|
||||
"""
|
||||
_size = non_default_params.get("size")
|
||||
if _size is not None:
|
||||
width, height = _size.split("x")
|
||||
optional_params["width"], optional_params["height"] = int(width), int(height)
|
||||
if non_default_params.get("n") is not None:
|
||||
optional_params["numberOfImages"] = non_default_params.get("n")
|
||||
if non_default_params.get("quality") is not None:
|
||||
if non_default_params.get("quality") in ("hd", "premium"):
|
||||
optional_params["quality"] = "premium"
|
||||
if non_default_params.get("quality") == "standard":
|
||||
optional_params["quality"] = "standard"
|
||||
return optional_params
|
||||
|
||||
@classmethod
|
||||
def transform_response_dict_to_openai_response(
|
||||
cls, model_response: ImageResponse, response_dict: dict
|
||||
) -> ImageResponse:
|
||||
"""
|
||||
Transform the response dict to the OpenAI response
|
||||
"""
|
||||
|
||||
nova_response = AmazonNovaCanvasTextToImageResponse(**response_dict)
|
||||
openai_images: List[Image] = []
|
||||
for _img in nova_response.get("images", []):
|
||||
openai_images.append(Image(b64_json=_img))
|
||||
|
||||
model_response.data = openai_images
|
||||
return model_response
|
||||
|
|
@ -266,6 +266,8 @@ class BedrockImageGeneration(BaseAWSLLM):
|
|||
"text_prompts": [{"text": prompt, "weight": 1}],
|
||||
**inference_params,
|
||||
}
|
||||
elif provider == "amazon":
|
||||
return dict(litellm.AmazonNovaCanvasConfig.transform_request_body(text=prompt, optional_params=optional_params))
|
||||
else:
|
||||
raise BedrockError(
|
||||
status_code=422, message=f"Unsupported model={model}, passed in"
|
||||
|
|
@ -301,6 +303,7 @@ class BedrockImageGeneration(BaseAWSLLM):
|
|||
config_class = (
|
||||
litellm.AmazonStability3Config
|
||||
if litellm.AmazonStability3Config._is_stability_3_model(model=model)
|
||||
else litellm.AmazonNovaCanvasConfig if litellm.AmazonNovaCanvasConfig._is_nova_model(model=model)
|
||||
else litellm.AmazonStabilityConfig
|
||||
)
|
||||
config_class.transform_response_dict_to_openai_response(
|
||||
|
|
|
|||
|
|
@ -6434,7 +6434,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-micro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000000035,
|
||||
|
|
@ -6472,7 +6472,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-lite-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.00000006,
|
||||
|
|
@ -6514,7 +6514,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-pro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.0000008,
|
||||
|
|
@ -6527,6 +6527,12 @@
|
|||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true
|
||||
},
|
||||
"1024-x-1024/50-steps/bedrock/amazon.nova-canvas-v1:0": {
|
||||
"max_input_tokens": 2600,
|
||||
"output_cost_per_image": 0.06,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"eu.amazon.nova-pro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
|
|
@ -7871,22 +7877,22 @@
|
|||
"mode": "image_generation"
|
||||
},
|
||||
"stability.sd3-5-large-v1:0": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.08,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-core-v1:0": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.04,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-core-v1:1": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.04,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
|
|
@ -7899,8 +7905,8 @@
|
|||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-ultra-v1:1": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.14,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
|
|
|
|||
|
|
@ -365,6 +365,63 @@ class AmazonStability3TextToImageResponse(TypedDict, total=False):
|
|||
finish_reasons: List[str]
|
||||
|
||||
|
||||
class AmazonNovaCanvasRequestBase(TypedDict, total=False):
|
||||
"""
|
||||
Base class for Amazon Nova Canvas API requests
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AmazonNovaCanvasImageGenerationConfig(TypedDict, total=False):
|
||||
"""
|
||||
Config for Amazon Nova Canvas Text to Image API
|
||||
|
||||
Ref: https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html
|
||||
"""
|
||||
|
||||
cfgScale: int
|
||||
seed: int
|
||||
quality: Literal["standard", "premium"]
|
||||
width: int
|
||||
height: int
|
||||
numberOfImages: int
|
||||
|
||||
|
||||
class AmazonNovaCanvasTextToImageParams(TypedDict, total=False):
|
||||
"""
|
||||
Params for Amazon Nova Canvas Text to Image API
|
||||
"""
|
||||
|
||||
text: str
|
||||
negativeText: str
|
||||
controlStrength: float
|
||||
controlMode: Literal["CANNY_EDIT", "SEGMENTATION"]
|
||||
conditionImage: str
|
||||
|
||||
|
||||
class AmazonNovaCanvasTextToImageRequest(AmazonNovaCanvasRequestBase, TypedDict, total=False):
|
||||
"""
|
||||
Request for Amazon Nova Canvas Text to Image API
|
||||
|
||||
Ref: https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html
|
||||
"""
|
||||
|
||||
textToImageParams: AmazonNovaCanvasTextToImageParams
|
||||
taskType: Literal["TEXT_IMAGE"]
|
||||
imageGenerationConfig: AmazonNovaCanvasImageGenerationConfig
|
||||
|
||||
|
||||
class AmazonNovaCanvasTextToImageResponse(TypedDict, total=False):
|
||||
"""
|
||||
Response for Amazon Nova Canvas Text to Image API
|
||||
|
||||
Ref: https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html
|
||||
"""
|
||||
|
||||
images: List[str]
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from botocore.awsrequest import AWSPreparedRequest
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -2427,6 +2427,7 @@ def get_optional_params_image_gen(
|
|||
config_class = (
|
||||
litellm.AmazonStability3Config
|
||||
if litellm.AmazonStability3Config._is_stability_3_model(model=model)
|
||||
else litellm.AmazonNovaCanvasConfig if litellm.AmazonNovaCanvasConfig._is_nova_model(model=model)
|
||||
else litellm.AmazonStabilityConfig
|
||||
)
|
||||
supported_params = config_class.get_supported_openai_params(model=model)
|
||||
|
|
|
|||
|
|
@ -6434,7 +6434,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-micro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.000000035,
|
||||
|
|
@ -6472,7 +6472,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-lite-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.00000006,
|
||||
|
|
@ -6514,7 +6514,7 @@
|
|||
"supports_response_schema": true
|
||||
},
|
||||
"us.amazon.nova-pro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
"max_output_tokens": 4096,
|
||||
"input_cost_per_token": 0.0000008,
|
||||
|
|
@ -6527,6 +6527,12 @@
|
|||
"supports_prompt_caching": true,
|
||||
"supports_response_schema": true
|
||||
},
|
||||
"1024-x-1024/50-steps/bedrock/amazon.nova-canvas-v1:0": {
|
||||
"max_input_tokens": 2600,
|
||||
"output_cost_per_image": 0.06,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"eu.amazon.nova-pro-v1:0": {
|
||||
"max_tokens": 4096,
|
||||
"max_input_tokens": 300000,
|
||||
|
|
@ -7871,22 +7877,22 @@
|
|||
"mode": "image_generation"
|
||||
},
|
||||
"stability.sd3-5-large-v1:0": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.08,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-core-v1:0": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.04,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-core-v1:1": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.04,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
|
|
@ -7899,8 +7905,8 @@
|
|||
"mode": "image_generation"
|
||||
},
|
||||
"stability.stable-image-ultra-v1:1": {
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"max_tokens": 77,
|
||||
"max_input_tokens": 77,
|
||||
"output_cost_per_image": 0.14,
|
||||
"litellm_provider": "bedrock",
|
||||
"mode": "image_generation"
|
||||
|
|
|
|||
|
|
@ -130,6 +130,16 @@ class TestBedrockSd1(BaseImageGenTest):
|
|||
return {"model": "bedrock/stability.sd3-large-v1:0"}
|
||||
|
||||
|
||||
class TestBedrockNovaCanvasTextToImage(BaseImageGenTest):
|
||||
def get_base_image_generation_call_args(self) -> dict:
|
||||
litellm.in_memory_llm_clients_cache = InMemoryCache()
|
||||
return {"model": "bedrock/amazon.nova-canvas-v1:0",
|
||||
"n": 1,
|
||||
"size": "320x320",
|
||||
"imageGenerationConfig": {"cfgScale":6.5,"seed":12},
|
||||
"taskType": "TEXT_IMAGE"}
|
||||
|
||||
|
||||
class TestOpenAIDalle3(BaseImageGenTest):
|
||||
def get_base_image_generation_call_args(self) -> dict:
|
||||
return {"model": "dall-e-3"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue