mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(databricks): charge the input rate for cache tokens on models with no cache pricing
The shared cost calculator treats a missing cache rate as free, so routing Databricks through it billed cached tokens at zero on the 14 entries that publish no cache pricing. On a 10,000 token prompt with 8,000 cache reads that is $0.0010000 against the correct $0.0050001, a fivefold undercharge. Those entries now declare cache rates equal to their input rate, which is what a model with no caching discount should charge, and a test pins every priced Databricks entry to declaring cache rates so no future entry can regress into it. Also repoints the provider-neutral generalization test off an id the new Opus 5 entry now shadows, adds backup-to-main parity tests for the five new entries, pins that Databricks Claude is never auto-injected with cache control despite reporting caching support, and trims the Sonnet 5 pricing note, which is served on an unauthenticated route.
This commit is contained in:
parent
6c23f5ffba
commit
da3dcb139d
5 changed files with 119 additions and 3 deletions
|
|
@ -14551,6 +14551,8 @@
|
|||
]
|
||||
},
|
||||
"databricks/databricks-bge-large-en": {
|
||||
"cache_creation_input_token_cost": 1.0003e-07,
|
||||
"cache_read_input_token_cost": 1.0003e-07,
|
||||
"input_cost_per_token": 1.0003e-07,
|
||||
"input_dbu_cost_per_token": 1.429e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -14904,7 +14906,7 @@
|
|||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"metadata": {
|
||||
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Anthropic's introductory launch rates (28.571 input / 142.857 output DBU) run through 2026-08-31. The standard rates listed here, equal to Sonnet 4.5 / 4.6, are used instead because pricing carries no expiry date, and undercharging past the window would let spend outrun enforced budgets."
|
||||
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Introductory launch rates of 28.571 input / 142.857 output DBU run through 2026-08-31; the standard rates are listed here because entries carry no expiry date."
|
||||
},
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.5000020000000002e-05,
|
||||
|
|
@ -15042,6 +15044,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-gemma-3-12b": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15273,6 +15277,8 @@
|
|||
"supports_prompt_caching": true
|
||||
},
|
||||
"databricks/databricks-gpt-oss-120b": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15288,6 +15294,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-gpt-oss-20b": {
|
||||
"cache_creation_input_token_cost": 7e-08,
|
||||
"cache_read_input_token_cost": 7e-08,
|
||||
"input_cost_per_token": 7e-08,
|
||||
"input_dbu_cost_per_token": 1e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15303,6 +15311,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-gte-large-en": {
|
||||
"cache_creation_input_token_cost": 1.2999000000000001e-07,
|
||||
"cache_read_input_token_cost": 1.2999000000000001e-07,
|
||||
"input_cost_per_token": 1.2999000000000001e-07,
|
||||
"input_dbu_cost_per_token": 1.857e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15318,6 +15328,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-llama-2-70b-chat": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15334,6 +15346,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-llama-4-maverick": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15350,6 +15364,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-1-405b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.00003e-06,
|
||||
"cache_read_input_token_cost": 5.00003e-06,
|
||||
"input_cost_per_token": 5.00003e-06,
|
||||
"input_dbu_cost_per_token": 7.1429e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15366,6 +15382,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-1-8b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15381,6 +15399,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-3-70b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15397,6 +15417,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-70b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.00002e-06,
|
||||
"cache_read_input_token_cost": 1.00002e-06,
|
||||
"input_cost_per_token": 1.00002e-06,
|
||||
"input_dbu_cost_per_token": 1.4286e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15413,6 +15435,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mixtral-8x7b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15429,6 +15453,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mpt-30b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.00002e-06,
|
||||
"cache_read_input_token_cost": 1.00002e-06,
|
||||
"input_cost_per_token": 1.00002e-06,
|
||||
"input_dbu_cost_per_token": 1.4286e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15445,6 +15471,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mpt-7b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
|
|||
|
|
@ -14551,6 +14551,8 @@
|
|||
]
|
||||
},
|
||||
"databricks/databricks-bge-large-en": {
|
||||
"cache_creation_input_token_cost": 1.0003e-07,
|
||||
"cache_read_input_token_cost": 1.0003e-07,
|
||||
"input_cost_per_token": 1.0003e-07,
|
||||
"input_dbu_cost_per_token": 1.429e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -14904,7 +14906,7 @@
|
|||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"metadata": {
|
||||
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Anthropic's introductory launch rates (28.571 input / 142.857 output DBU) run through 2026-08-31. The standard rates listed here, equal to Sonnet 4.5 / 4.6, are used instead because pricing carries no expiry date, and undercharging past the window would let spend outrun enforced budgets."
|
||||
"notes": "Input/output cost per token is dbu cost * $0.070. Number provided for reference, '*_dbu_cost_per_token' used in actual calculation. Introductory launch rates of 28.571 input / 142.857 output DBU run through 2026-08-31; the standard rates are listed here because entries carry no expiry date."
|
||||
},
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.5000020000000002e-05,
|
||||
|
|
@ -15042,6 +15044,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-gemma-3-12b": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15273,6 +15277,8 @@
|
|||
"supports_prompt_caching": true
|
||||
},
|
||||
"databricks/databricks-gpt-oss-120b": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15288,6 +15294,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-gpt-oss-20b": {
|
||||
"cache_creation_input_token_cost": 7e-08,
|
||||
"cache_read_input_token_cost": 7e-08,
|
||||
"input_cost_per_token": 7e-08,
|
||||
"input_dbu_cost_per_token": 1e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15303,6 +15311,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-gte-large-en": {
|
||||
"cache_creation_input_token_cost": 1.2999000000000001e-07,
|
||||
"cache_read_input_token_cost": 1.2999000000000001e-07,
|
||||
"input_cost_per_token": 1.2999000000000001e-07,
|
||||
"input_dbu_cost_per_token": 1.857e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15318,6 +15328,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-llama-2-70b-chat": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15334,6 +15346,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-llama-4-maverick": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15350,6 +15364,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-1-405b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.00003e-06,
|
||||
"cache_read_input_token_cost": 5.00003e-06,
|
||||
"input_cost_per_token": 5.00003e-06,
|
||||
"input_dbu_cost_per_token": 7.1429e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15366,6 +15382,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-1-8b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.5000999999999998e-07,
|
||||
"cache_read_input_token_cost": 1.5000999999999998e-07,
|
||||
"input_cost_per_token": 1.5000999999999998e-07,
|
||||
"input_dbu_cost_per_token": 2.1429999999999996e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15381,6 +15399,8 @@
|
|||
"source": "https://www.databricks.com/product/pricing/foundation-model-serving"
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-3-70b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15397,6 +15417,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-meta-llama-3-70b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.00002e-06,
|
||||
"cache_read_input_token_cost": 1.00002e-06,
|
||||
"input_cost_per_token": 1.00002e-06,
|
||||
"input_dbu_cost_per_token": 1.4286e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15413,6 +15435,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mixtral-8x7b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15429,6 +15453,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mpt-30b-instruct": {
|
||||
"cache_creation_input_token_cost": 1.00002e-06,
|
||||
"cache_read_input_token_cost": 1.00002e-06,
|
||||
"input_cost_per_token": 1.00002e-06,
|
||||
"input_dbu_cost_per_token": 1.4286e-05,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
@ -15445,6 +15471,8 @@
|
|||
"supports_tool_choice": true
|
||||
},
|
||||
"databricks/databricks-mpt-7b-instruct": {
|
||||
"cache_creation_input_token_cost": 5.0001e-07,
|
||||
"cache_read_input_token_cost": 5.0001e-07,
|
||||
"input_cost_per_token": 5.0001e-07,
|
||||
"input_dbu_cost_per_token": 7.143e-06,
|
||||
"litellm_provider": "databricks",
|
||||
|
|
|
|||
|
|
@ -1599,6 +1599,14 @@ class TestEnableAnthropicPromptCaching:
|
|||
assert supports_prompt_caching(model=model, custom_llm_provider=provider) is True
|
||||
assert self._points(model=model, provider=provider) == []
|
||||
|
||||
def test_databricks_claude_not_injected_despite_caching_support(self, monkeypatch):
|
||||
from litellm.utils import supports_prompt_caching
|
||||
|
||||
monkeypatch.setattr(litellm, "enable_anthropic_prompt_caching", True)
|
||||
model = "databricks/databricks-claude-sonnet-4-5"
|
||||
assert supports_prompt_caching(model=model, custom_llm_provider="databricks") is True
|
||||
assert self._points(model=model, provider="databricks") == []
|
||||
|
||||
def test_model_without_caching_support_not_injected(self, monkeypatch):
|
||||
monkeypatch.setattr(litellm, "enable_anthropic_prompt_caching", True)
|
||||
assert self._points(model="anthropic.claude-3-5-sonnet-20240620-v1:0", provider="bedrock") == []
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ def test_shipped_rules_flag_unmapped_fable_as_always_on_thinking(shipped_cost_ma
|
|||
"model,provider",
|
||||
[
|
||||
("claude-opus-4-9@20260101", "vertex_ai"),
|
||||
("databricks-claude-opus-5-1", "databricks"),
|
||||
("databricks-claude-haiku-5-1", "databricks"),
|
||||
],
|
||||
)
|
||||
def test_shipped_rules_are_provider_neutral_for_unmapped_ids(shipped_cost_map, model, provider):
|
||||
|
|
@ -388,6 +388,8 @@ def test_shipped_rules_are_provider_neutral_for_unmapped_ids(shipped_cost_map, m
|
|||
assert info["supports_adaptive_thinking"] is True
|
||||
assert info["supports_mid_conversation_system"] is True
|
||||
assert info["supports_function_calling"] is True
|
||||
assert not info.get("input_cost_per_token")
|
||||
assert not info.get("output_cost_per_token")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import json
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
import pytest
|
||||
|
|
@ -7,6 +9,17 @@ import litellm
|
|||
from litellm.llms.databricks.cost_calculator import cost_per_token
|
||||
from litellm.types.utils import ModelInfo, Usage
|
||||
|
||||
REPO_ROOT: Final = Path(__file__).parents[4]
|
||||
MAIN_PRICES: Final = REPO_ROOT / "model_prices_and_context_window.json"
|
||||
BACKUP_PRICES: Final = REPO_ROOT / "litellm" / "model_prices_and_context_window_backup.json"
|
||||
NEW_MODELS: Final = (
|
||||
"databricks/databricks-claude-opus-4-7",
|
||||
"databricks/databricks-claude-opus-4-8",
|
||||
"databricks/databricks-claude-opus-5",
|
||||
"databricks/databricks-claude-sonnet-5",
|
||||
"databricks/databricks-claude-fable-5",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def local_model_cost_map(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
||||
|
|
@ -91,6 +104,43 @@ def test_new_models_carry_cache_pricing(local_model_cost_map: None, model: str)
|
|||
assert info["supports_prompt_caching"] is True
|
||||
|
||||
|
||||
def test_every_priced_databricks_model_declares_cache_rates(local_model_cost_map: None) -> None:
|
||||
undeclared: Final = [
|
||||
model
|
||||
for model, info in litellm.model_cost.items()
|
||||
if model.startswith("databricks/")
|
||||
and info.get("input_cost_per_token") is not None
|
||||
and info.get("cache_read_input_token_cost") is None
|
||||
]
|
||||
|
||||
assert undeclared == []
|
||||
|
||||
|
||||
def test_models_without_a_cache_discount_bill_cache_tokens_at_the_input_rate(
|
||||
local_model_cost_map: None,
|
||||
) -> None:
|
||||
model: Final = "databricks/databricks-meta-llama-3-3-70b-instruct"
|
||||
info: Final = _model_info(model)
|
||||
usage: Final = Usage(
|
||||
prompt_tokens=10000,
|
||||
completion_tokens=100,
|
||||
total_tokens=10100,
|
||||
cache_read_input_tokens=8000,
|
||||
)
|
||||
|
||||
prompt_cost, _ = cost_per_token(model=model, usage=usage)
|
||||
|
||||
assert prompt_cost == pytest.approx(10000 * info["input_cost_per_token"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", NEW_MODELS)
|
||||
def test_backup_price_map_matches_main(model: str) -> None:
|
||||
main_cost: Final = json.loads(MAIN_PRICES.read_text())
|
||||
backup_cost: Final = json.loads(BACKUP_PRICES.read_text())
|
||||
|
||||
assert backup_cost.get(model) == main_cost.get(model)
|
||||
|
||||
|
||||
def test_sonnet_5_ships_standard_rates_not_introductory(local_model_cost_map: None) -> None:
|
||||
sonnet_5: Final = _model_info("databricks/databricks-claude-sonnet-5")
|
||||
sonnet_4_6: Final = _model_info("databricks/databricks-claude-sonnet-4-6")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue