mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
Update utils.py
This commit is contained in:
parent
6004f53d1b
commit
c1b9463d03
1 changed files with 19 additions and 38 deletions
|
|
@ -668,29 +668,18 @@ def generic_cost_per_token( # noqa: PLR0915
|
|||
image_tokens = prompt_tokens_details["image_tokens"]
|
||||
|
||||
# Check for double-counting: sum of details > prompt_tokens means overlap
|
||||
accounted_tokens = (
|
||||
text_tokens + cache_hit + audio_tokens + cache_creation + image_tokens
|
||||
)
|
||||
accounted_tokens = text_tokens + cache_hit + audio_tokens + cache_creation + image_tokens
|
||||
has_double_counting = cache_hit > 0 and accounted_tokens > usage.prompt_tokens
|
||||
|
||||
# Some models use alternative billing dimensions (image_count, character_count,
|
||||
# video_length_seconds) that account for prompt_tokens without being included
|
||||
# in the per-token detail fields. When these are active, a gap between
|
||||
# accounted_tokens and prompt_tokens is expected and must NOT be filled.
|
||||
has_image_count_billing = prompt_tokens_details["image_count"] > 0
|
||||
|
||||
# Some models use alternative billing dimensions (character_count, video_length_seconds)
|
||||
# that account for prompt_tokens without being included in the per-token detail fields.
|
||||
# When these are active, a gap between accounted_tokens and prompt_tokens is expected
|
||||
# and must NOT be filled. Note: image_count is additive billing, not alternative.
|
||||
has_non_token_alternative_billing = (
|
||||
prompt_tokens_details["character_count"] > 0
|
||||
or prompt_tokens_details["video_length_seconds"] > 0
|
||||
)
|
||||
has_alternative_billing = (
|
||||
has_image_count_billing or has_non_token_alternative_billing
|
||||
)
|
||||
should_fill_unaccounted_tokens = (
|
||||
accounted_tokens < usage.prompt_tokens
|
||||
and not has_non_token_alternative_billing
|
||||
and not has_image_count_billing
|
||||
)
|
||||
|
||||
|
||||
if has_double_counting:
|
||||
# Double-counting fix (xAI etc.): recalculate text_tokens from scratch
|
||||
# Clamp to 0 to prevent negative cost when cache_hit exceeds prompt_tokens
|
||||
|
|
@ -703,30 +692,23 @@ def generic_cost_per_token( # noqa: PLR0915
|
|||
- image_tokens,
|
||||
)
|
||||
prompt_tokens_details["text_tokens"] = text_tokens
|
||||
elif text_tokens == 0 and not has_alternative_billing:
|
||||
# text_tokens not set by provider and no alternative billing dimensions:
|
||||
# calculate text_tokens as the remainder of prompt_tokens
|
||||
text_tokens = max(
|
||||
0,
|
||||
usage.prompt_tokens
|
||||
- cache_hit
|
||||
- audio_tokens
|
||||
- cache_creation
|
||||
- image_tokens,
|
||||
)
|
||||
prompt_tokens_details["text_tokens"] = text_tokens
|
||||
elif should_fill_unaccounted_tokens:
|
||||
elif accounted_tokens < usage.prompt_tokens and not has_non_token_alternative_billing:
|
||||
# Unaccounted tokens fix: inline documents (PDF, DOCX, etc.) are counted
|
||||
# in prompt_tokens by the provider but not broken out into any detail field.
|
||||
# Add the gap to text_tokens so they are costed at input_cost_per_token.
|
||||
#
|
||||
# The guard above skips filling when ANY alternative pricing dimension is
|
||||
# present (character_count, video_length_seconds, or image_count), since
|
||||
# the gap may represent tokens already billed through those dimensions
|
||||
# and converting them to text_tokens would cause double-billing.
|
||||
# This handles both cases:
|
||||
# 1. text_tokens=0 (provider didn't set it) - gap fills the entire remainder
|
||||
# 2. text_tokens>0 but < total (mixed content like PDF+text) - gap fills remainder
|
||||
#
|
||||
# Skip filling only when non-token alternative billing is active
|
||||
# (character_count, video_length_seconds), since those dimensions
|
||||
# replace token-based billing entirely. image_count is additive and should
|
||||
# not prevent gap-filling for unaccounted document tokens.
|
||||
unaccounted_tokens = usage.prompt_tokens - accounted_tokens
|
||||
prompt_tokens_details["text_tokens"] += unaccounted_tokens
|
||||
|
||||
|
||||
|
||||
(
|
||||
prompt_base_cost,
|
||||
completion_base_cost,
|
||||
|
|
@ -736,7 +718,7 @@ def generic_cost_per_token( # noqa: PLR0915
|
|||
) = _get_token_base_cost(
|
||||
model_info=model_info, usage=usage, service_tier=service_tier
|
||||
)
|
||||
|
||||
|
||||
prompt_cost = _calculate_input_cost(
|
||||
prompt_tokens_details=prompt_tokens_details,
|
||||
model_info=model_info,
|
||||
|
|
@ -746,7 +728,6 @@ def generic_cost_per_token( # noqa: PLR0915
|
|||
cache_creation_cost_above_1hr=cache_creation_cost_above_1hr,
|
||||
service_tier=service_tier,
|
||||
)
|
||||
|
||||
## CALCULATE OUTPUT COST
|
||||
text_tokens = 0
|
||||
audio_tokens = 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue