Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Oct 30, 2025

📄 70% (0.70x) speedup for OpenAIWhisperAudioTranscriptionConfig.map_openai_params in litellm/llms/openai/transcriptions/whisper_transformation.py

⏱️ Runtime : 204 microseconds 120 microseconds (best of 362 runs)

📝 Explanation and details

The optimization replaces a linear search approach with set-based operations for parameter filtering. The key changes are:

What was optimized:

  1. Converted list to set: supported_params = set(self.get_supported_openai_params(model)) converts the supported parameters list to a set for O(1) lookup operations
  2. Used set intersection: supported_params.intersection(non_default_params) efficiently finds only the keys that exist in both collections
  3. Eliminated redundant lookups: Instead of checking if k in supported_params for every parameter, the code now only processes parameters that are guaranteed to be supported

Why it's faster:

  • The original code performed O(n×m) operations where n = number of input parameters and m = number of supported parameters (5). Each k in supported_params was a linear search through the list
  • The optimized version performs O(n) set intersection plus O(k) assignments where k = number of matching parameters, which is always ≤ min(n,m)
  • Set intersection is highly optimized in Python's C implementation

Performance characteristics:

  • Small inputs: Shows modest slowdown (20-40%) due to set creation overhead, as seen in basic test cases
  • Large inputs with many unsupported parameters: Shows dramatic speedup (97-276%) because it avoids checking every unsupported parameter against the supported list. The test_large_scale_many_unsupported_params shows 276% speedup when processing 1000 parameters where only 3 are supported
  • Mixed scenarios: Performance scales with the ratio of supported to total parameters - more unsupported parameters = better relative performance

This optimization is particularly effective for scenarios with large parameter dictionaries containing mostly unsupported keys, which is common in API parameter filtering.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 86 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 2 Passed
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
from typing import List

# imports
import pytest  # used for our unit tests
from litellm.llms.openai.transcriptions.whisper_transformation import \
    OpenAIWhisperAudioTranscriptionConfig

# unit tests

@pytest.fixture
def whisper_config():
    # Fixture to provide a fresh instance for each test
    return OpenAIWhisperAudioTranscriptionConfig()

# 1. Basic Test Cases

def test_basic_single_supported_param(whisper_config):
    # Test mapping a single supported param
    non_default_params = {"language": "en"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.24μs -> 2.03μs (39.1% slower)

def test_basic_multiple_supported_params(whisper_config):
    # Test mapping multiple supported params
    non_default_params = {"language": "fr", "prompt": "Say hello", "temperature": 0.5}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.52μs -> 2.17μs (29.8% slower)

def test_basic_mixed_supported_and_unsupported_params(whisper_config):
    # Test mapping with both supported and unsupported params
    non_default_params = {"language": "es", "foo": "bar", "response_format": "json"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.47μs -> 2.07μs (28.9% slower)

def test_basic_empty_non_default_params(whisper_config):
    # Test with empty non_default_params
    non_default_params = {}
    optional_params = {"prompt": "existing"}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.06μs -> 1.71μs (38.0% slower)

def test_basic_optional_params_preserved_and_updated(whisper_config):
    # Test that optional_params is updated and preserved
    non_default_params = {"language": "de"}
    optional_params = {"prompt": "existing"}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.18μs -> 1.88μs (37.5% slower)

# 2. Edge Test Cases

def test_edge_none_as_value(whisper_config):
    # Test mapping where value is None
    non_default_params = {"language": None, "prompt": "Say something"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.34μs -> 2.01μs (33.5% slower)

def test_edge_empty_string_as_value(whisper_config):
    # Test mapping where value is empty string
    non_default_params = {"language": "", "response_format": ""}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.33μs -> 1.99μs (33.2% slower)

def test_edge_non_string_keys(whisper_config):
    # Test mapping where keys are not strings
    non_default_params = {1: "one", "prompt": "Say hi"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.47μs -> 1.91μs (23.0% slower)

def test_edge_supported_param_overwrites_optional(whisper_config):
    # Test that supported param in non_default_params overwrites optional_params
    non_default_params = {"temperature": 0.9}
    optional_params = {"temperature": 0.1}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.27μs -> 1.80μs (29.4% slower)

def test_edge_unsupported_param_does_not_overwrite(whisper_config):
    # Test that unsupported param does not overwrite optional_params
    non_default_params = {"foo": "bar"}
    optional_params = {"foo": "baz"}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.18μs -> 1.66μs (29.2% slower)

def test_edge_case_sensitive_keys(whisper_config):
    # Test that keys are case-sensitive
    non_default_params = {"Language": "en", "language": "fr"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.37μs -> 1.87μs (26.5% slower)

def test_edge_drop_params_flag_unused(whisper_config):
    # Test that drop_params flag has no effect
    non_default_params = {"prompt": "Test"}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params.copy(), "whisper-1", False); result1 = codeflash_output # 1.19μs -> 1.87μs (36.3% slower)
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params.copy(), "whisper-1", True); result2 = codeflash_output # 455ns -> 725ns (37.2% slower)

def test_edge_supported_param_with_list_value(whisper_config):
    # Test mapping where value is a list
    non_default_params = {"timestamp_granularities": ["segment", "word"]}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.22μs -> 1.74μs (29.9% slower)

def test_edge_optional_params_with_extra_keys(whisper_config):
    # Test that extra keys in optional_params are preserved
    non_default_params = {"language": "it"}
    optional_params = {"extra": "value"}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.16μs -> 1.83μs (36.8% slower)

# 3. Large Scale Test Cases

def test_large_scale_many_supported_params(whisper_config):
    # Test with many supported params (all supported keys)
    non_default_params = {
        "language": "zh",
        "prompt": "你好",
        "response_format": "text",
        "temperature": 0.7,
        "timestamp_granularities": ["word"]
    }
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.64μs -> 2.21μs (25.8% slower)

def test_large_scale_many_unsupported_params(whisper_config):
    # Test with many unsupported params
    non_default_params = {f"foo{i}": i for i in range(100)}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 5.18μs -> 2.62μs (97.8% faster)

def test_large_scale_mixed_supported_and_unsupported(whisper_config):
    # Test with a mix of supported and unsupported params
    non_default_params = {f"foo{i}": i for i in range(100)}
    # Add supported params
    non_default_params.update({
        "language": "ko",
        "prompt": "안녕하세요",
        "response_format": "text",
        "temperature": 0.2,
        "timestamp_granularities": ["segment"]
    })
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 5.77μs -> 3.44μs (67.7% faster)
    expected = {
        "language": "ko",
        "prompt": "안녕하세요",
        "response_format": "text",
        "temperature": 0.2,
        "timestamp_granularities": ["segment"]
    }

def test_large_scale_optional_params_with_many_keys(whisper_config):
    # Test with large optional_params, only supported keys should be updated
    optional_params = {f"foo{i}": i for i in range(100)}
    optional_params.update({"prompt": "old", "language": "old"})
    non_default_params = {"prompt": "new", "language": "new"}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.39μs -> 2.01μs (30.9% slower)
    # Only 'prompt' and 'language' should be updated
    for i in range(100):
        pass

def test_large_scale_empty_dicts(whisper_config):
    # Test with empty dicts for both params
    non_default_params = {}
    optional_params = {}
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.07μs -> 1.70μs (37.0% slower)

def test_large_scale_overwrite_all_supported_keys(whisper_config):
    # Test overwriting all supported keys in optional_params
    optional_params = {
        "language": "old",
        "prompt": "old",
        "response_format": "old",
        "temperature": "old",
        "timestamp_granularities": "old"
    }
    non_default_params = {
        "language": "new",
        "prompt": "new",
        "response_format": "new",
        "temperature": "new",
        "timestamp_granularities": "new"
    }
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 1.67μs -> 2.38μs (29.7% slower)

def test_large_scale_unsupported_keys_do_not_affect_supported(whisper_config):
    # Test that a large number of unsupported keys do not affect supported keys
    non_default_params = {f"unsupported{i}": i for i in range(500)}
    non_default_params.update({"language": "ru"})
    optional_params = {f"unsupported{i}": "old" for i in range(500)}
    optional_params.update({"language": "old"})
    codeflash_output = whisper_config.map_openai_params(non_default_params, optional_params, "whisper-1", False); result = codeflash_output # 21.0μs -> 7.27μs (189% faster)
    # Only 'language' should be updated
    for i in range(500):
        pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from typing import List

# imports
import pytest
from litellm.llms.openai.transcriptions.whisper_transformation import \
    OpenAIWhisperAudioTranscriptionConfig

# unit tests

@pytest.fixture
def config():
    # Fixture for the class instance
    return OpenAIWhisperAudioTranscriptionConfig()

# --- Basic Test Cases ---

def test_basic_single_supported_param(config):
    # Test mapping a single supported param
    non_default_params = {"language": "en"}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.21μs -> 1.95μs (38.0% slower)

def test_basic_multiple_supported_params(config):
    # Test mapping multiple supported params
    non_default_params = {
        "language": "en",
        "prompt": "Say hello",
        "temperature": 0.5,
    }
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.48μs -> 2.12μs (30.1% slower)

def test_basic_unsupported_param(config):
    # Test that unsupported params are not mapped
    non_default_params = {
        "language": "en",
        "foo": "bar",  # unsupported
    }
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.27μs -> 1.83μs (30.7% slower)

def test_basic_optional_params_preserved(config):
    # Test that optional_params are preserved and updated
    non_default_params = {"prompt": "Test"}
    optional_params = {"language": "fr"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.17μs -> 1.84μs (36.4% slower)

def test_basic_overwrite_existing_optional_param(config):
    # Test that non_default_params overwrite existing values in optional_params
    non_default_params = {"language": "es"}
    optional_params = {"language": "fr"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.13μs -> 1.81μs (37.9% slower)

# --- Edge Test Cases ---

def test_edge_empty_non_default_params(config):
    # Test with empty non_default_params
    non_default_params = {}
    optional_params = {"language": "en"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 977ns -> 1.52μs (35.8% slower)

def test_edge_empty_optional_params(config):
    # Test with empty optional_params and non_default_params
    non_default_params = {}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 936ns -> 1.59μs (41.0% slower)

def test_edge_all_unsupported_params(config):
    # Test with only unsupported params in non_default_params
    non_default_params = {"foo": "bar", "baz": 123}
    optional_params = {"language": "en"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.24μs -> 1.60μs (22.2% slower)

def test_edge_supported_param_with_none_value(config):
    # Test supported param with None value
    non_default_params = {"language": None}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.15μs -> 1.86μs (38.4% slower)

def test_edge_supported_param_with_falsey_value(config):
    # Test supported param with falsey value
    non_default_params = {"temperature": 0}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.18μs -> 1.79μs (34.2% slower)

def test_edge_supported_param_with_list_value(config):
    # Test supported param with a list value
    non_default_params = {"timestamp_granularities": ["segment", "word"]}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.19μs -> 1.86μs (35.8% slower)

def test_edge_case_sensitive_param_name(config):
    # Test that param names are case-sensitive
    non_default_params = {"Language": "en"}  # should not match "language"
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.11μs -> 1.61μs (31.0% slower)

def test_edge_optional_params_with_unsupported_key(config):
    # Test that optional_params with unsupported keys are preserved
    non_default_params = {"language": "en"}
    optional_params = {"foo": "bar"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.16μs -> 1.84μs (36.6% slower)

def test_edge_drop_params_argument_unused(config):
    # Ensure drop_params argument does not affect behavior (since it's unused)
    non_default_params = {"language": "en"}
    optional_params = {}
    model = "whisper-1"
    codeflash_output = config.map_openai_params(non_default_params, optional_params.copy(), model, True); result1 = codeflash_output # 1.15μs -> 1.82μs (37.2% slower)
    codeflash_output = config.map_openai_params(non_default_params, optional_params.copy(), model, False); result2 = codeflash_output # 446ns -> 671ns (33.5% slower)

def test_edge_non_default_params_is_not_mutated(config):
    # Ensure non_default_params is not mutated
    non_default_params = {"language": "en"}
    optional_params = {}
    model = "whisper-1"
    config.map_openai_params(non_default_params, optional_params, model, False) # 1.14μs -> 1.78μs (35.9% slower)

# --- Large Scale Test Cases ---

def test_large_scale_many_supported_params(config):
    # Test with all supported params present
    non_default_params = {
        "language": "en",
        "prompt": "Say something",
        "response_format": "json",
        "temperature": 0.8,
        "timestamp_granularities": ["segment", "word"],
    }
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.69μs -> 2.50μs (32.4% slower)

def test_large_scale_many_unsupported_params(config):
    # Test with many unsupported params (up to 1000), only supported ones should be mapped
    non_default_params = {f"foo{i}": i for i in range(995)}
    # Add a few supported params
    non_default_params.update({
        "language": "en",
        "prompt": "Bulk test",
        "temperature": 0.9,
    })
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 42.2μs -> 11.2μs (276% faster)
    # Ensure none of the unsupported keys are present
    for i in range(995):
        pass

def test_large_scale_optional_params_with_supported_and_unsupported(config):
    # Test with large optional_params and non_default_params
    optional_params = {f"bar{i}": i for i in range(995)}
    optional_params.update({"response_format": "text"})
    non_default_params = {"response_format": "json"}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.31μs -> 1.88μs (29.9% slower)
    for i in range(995):
        pass

def test_large_scale_all_supported_params_overwrite(config):
    # Test all supported params overwrite optional_params
    non_default_params = {
        "language": "it",
        "prompt": "Ciao",
        "response_format": "xml",
        "temperature": 0.3,
        "timestamp_granularities": ["word"],
    }
    optional_params = {
        "language": "en",
        "prompt": "Hello",
        "response_format": "json",
        "temperature": 0.9,
        "timestamp_granularities": ["segment"],
    }
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 1.72μs -> 2.47μs (30.4% slower)

def test_large_scale_no_supported_params(config):
    # Test with large non_default_params, none supported
    non_default_params = {f"key{i}": i for i in range(1000)}
    optional_params = {}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 41.9μs -> 11.6μs (261% faster)

def test_large_scale_performance(config):
    # Test performance with large dicts (not a timing test, but ensures no crash)
    non_default_params = {f"x{i}": i for i in range(990)}
    non_default_params.update({"language": "en"})
    optional_params = {f"y{i}": i for i in range(990)}
    model = "whisper-1"
    drop_params = False
    codeflash_output = config.map_openai_params(non_default_params, optional_params, model, drop_params); result = codeflash_output # 40.0μs -> 11.8μs (240% faster)
    for i in range(990):
        pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from litellm.llms.openai.transcriptions.whisper_transformation import OpenAIWhisperAudioTranscriptionConfig

def test_OpenAIWhisperAudioTranscriptionConfig_map_openai_params():
    OpenAIWhisperAudioTranscriptionConfig.map_openai_params(OpenAIWhisperAudioTranscriptionConfig(), {'prompt': ''}, {}, '', True)
🔎 Concolic Coverage Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
codeflash_concolic_zbim32de/tmp33s393py/test_concolic_coverage.py::test_OpenAIWhisperAudioTranscriptionConfig_map_openai_params 1.33μs 2.21μs -40.1%⚠️

To edit these changes git checkout codeflash/optimize-OpenAIWhisperAudioTranscriptionConfig.map_openai_params-mhdmo1a7 and push.

Codeflash Static Badge

The optimization replaces a linear search approach with set-based operations for parameter filtering. The key changes are:

**What was optimized:**
1. **Converted list to set**: `supported_params = set(self.get_supported_openai_params(model))` converts the supported parameters list to a set for O(1) lookup operations
2. **Used set intersection**: `supported_params.intersection(non_default_params)` efficiently finds only the keys that exist in both collections
3. **Eliminated redundant lookups**: Instead of checking `if k in supported_params` for every parameter, the code now only processes parameters that are guaranteed to be supported

**Why it's faster:**
- The original code performed O(n×m) operations where n = number of input parameters and m = number of supported parameters (5). Each `k in supported_params` was a linear search through the list
- The optimized version performs O(n) set intersection plus O(k) assignments where k = number of matching parameters, which is always ≤ min(n,m)
- Set intersection is highly optimized in Python's C implementation

**Performance characteristics:**
- **Small inputs**: Shows modest slowdown (20-40%) due to set creation overhead, as seen in basic test cases
- **Large inputs with many unsupported parameters**: Shows dramatic speedup (97-276%) because it avoids checking every unsupported parameter against the supported list. The `test_large_scale_many_unsupported_params` shows 276% speedup when processing 1000 parameters where only 3 are supported
- **Mixed scenarios**: Performance scales with the ratio of supported to total parameters - more unsupported parameters = better relative performance

This optimization is particularly effective for scenarios with large parameter dictionaries containing mostly unsupported keys, which is common in API parameter filtering.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 October 30, 2025 16:17
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Oct 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant