mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(cost): tier-aware fallback for Gemini image tokens; avoid double-billing per-second audio/video
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
ca5bcfc8a8
commit
e6ec88b1b7
2 changed files with 22 additions and 18 deletions
|
|
@ -581,29 +581,30 @@ def _calculate_input_cost(
|
|||
### AUDIO COST
|
||||
if prompt_tokens_details["audio_tokens"]:
|
||||
audio_cost_key = _get_service_tier_cost_key("input_cost_per_audio_token", service_tier)
|
||||
if model_info.get(audio_cost_key) is None:
|
||||
prompt_cost += float(prompt_tokens_details["audio_tokens"]) * prompt_base_cost
|
||||
else:
|
||||
if model_info.get(audio_cost_key) is not None:
|
||||
prompt_cost += calculate_cost_component(model_info, audio_cost_key, prompt_tokens_details["audio_tokens"])
|
||||
elif model_info.get("input_cost_per_audio_per_second") is None:
|
||||
prompt_cost += float(prompt_tokens_details["audio_tokens"]) * prompt_base_cost
|
||||
|
||||
### IMAGE TOKEN COST
|
||||
if prompt_tokens_details["image_tokens"]:
|
||||
# For image token costs:
|
||||
# First check if input_cost_per_image_token is available. If not, default to generic input_cost_per_token.
|
||||
image_token_cost_key = "input_cost_per_image_token"
|
||||
if model_info.get(image_token_cost_key) is None:
|
||||
image_token_cost_key = "input_cost_per_token"
|
||||
prompt_cost += calculate_cost_component(model_info, image_token_cost_key, prompt_tokens_details["image_tokens"])
|
||||
if model_info.get(image_token_cost_key) is not None:
|
||||
prompt_cost += calculate_cost_component(
|
||||
model_info, image_token_cost_key, prompt_tokens_details["image_tokens"]
|
||||
)
|
||||
else:
|
||||
prompt_cost += float(prompt_tokens_details["image_tokens"]) * prompt_base_cost
|
||||
|
||||
### VIDEO TOKEN COST
|
||||
if prompt_tokens_details["video_tokens"]:
|
||||
video_token_cost_key = "input_cost_per_video_token"
|
||||
if model_info.get(video_token_cost_key) is None:
|
||||
prompt_cost += float(prompt_tokens_details["video_tokens"]) * prompt_base_cost
|
||||
else:
|
||||
if model_info.get(video_token_cost_key) is not None:
|
||||
prompt_cost += calculate_cost_component(
|
||||
model_info, video_token_cost_key, prompt_tokens_details["video_tokens"]
|
||||
)
|
||||
elif model_info.get("input_cost_per_video_per_second") is None:
|
||||
prompt_cost += float(prompt_tokens_details["video_tokens"]) * prompt_base_cost
|
||||
|
||||
### CACHE WRITING COST - Now uses tiered pricing
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -379,12 +379,12 @@ def test_audio_input_tokens_gemini_priced_at_text_rate():
|
|||
)
|
||||
|
||||
|
||||
def test_audio_video_input_tokens_gemini_use_above_200k_tier():
|
||||
"""Regression for LIT-4474: audio/video fallbacks must honor the >200k long-context tier.
|
||||
def test_audio_video_image_input_tokens_gemini_use_above_200k_tier():
|
||||
"""Regression for LIT-4474: audio/video/image fallbacks must honor the >200k long-context tier.
|
||||
|
||||
Falling back to the raw un-tiered input_cost_per_token undercounts when the request crosses
|
||||
the 200k boundary; audio and video should be priced at input_cost_per_token_above_200k_tokens
|
||||
like text.
|
||||
the 200k boundary; audio, video and image tokens should be priced at
|
||||
input_cost_per_token_above_200k_tokens like text.
|
||||
"""
|
||||
model = "gemini-3-pro-preview"
|
||||
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
|
||||
|
|
@ -393,11 +393,13 @@ def test_audio_video_input_tokens_gemini_use_above_200k_tier():
|
|||
model_cost_map = litellm.model_cost[f"gemini/{model}"]
|
||||
hi_rate = model_cost_map["input_cost_per_token_above_200k_tokens"]
|
||||
assert hi_rate != model_cost_map["input_cost_per_token"]
|
||||
assert model_cost_map.get("input_cost_per_image_token") is None
|
||||
|
||||
text_tokens = 100000
|
||||
audio_tokens = 60000
|
||||
video_tokens = 80000
|
||||
prompt_tokens = text_tokens + audio_tokens + video_tokens
|
||||
audio_tokens = 40000
|
||||
video_tokens = 60000
|
||||
image_tokens = 40000
|
||||
prompt_tokens = text_tokens + audio_tokens + video_tokens + image_tokens
|
||||
usage = Usage(
|
||||
completion_tokens=0,
|
||||
prompt_tokens=prompt_tokens,
|
||||
|
|
@ -406,6 +408,7 @@ def test_audio_video_input_tokens_gemini_use_above_200k_tier():
|
|||
text_tokens=text_tokens,
|
||||
audio_tokens=audio_tokens,
|
||||
video_tokens=video_tokens,
|
||||
image_tokens=image_tokens,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue