@@ -416,6 +416,9 @@ def __init__( # noqa: PLR0915
416
416
417
417
# Initialize model ID to deployment index mapping for O(1) lookups
418
418
self .model_id_to_deployment_index_map : Dict [str , int ] = {}
419
+ # Initialize model name to deployment indices mapping for O(1) lookups
420
+ # Maps model_name -> list of indices in model_list
421
+ self .model_name_to_deployment_indices : Dict [str , List [int ]] = {}
419
422
420
423
if model_list is not None :
421
424
# Build model index immediately to enable O(1) lookups from the start
@@ -5097,6 +5100,7 @@ def set_model_list(self, model_list: list):
5097
5100
original_model_list = copy .deepcopy (model_list )
5098
5101
self .model_list = []
5099
5102
self .model_id_to_deployment_index_map = {} # Reset the index
5103
+ self .model_name_to_deployment_indices = {} # Reset the model_name index
5100
5104
# we add api_base/api_key each model so load balancing between azure/gpt on api_base1 and api_base2 works
5101
5105
5102
5106
for model in original_model_list :
@@ -5138,6 +5142,9 @@ def set_model_list(self, model_list: list):
5138
5142
f"\n Initialized Model List { self .get_model_names ()} "
5139
5143
)
5140
5144
self .model_names = [m ["model_name" ] for m in model_list ]
5145
+
5146
+ # Build model_name index for O(1) lookups
5147
+ self ._build_model_name_index (self .model_list )
5141
5148
5142
5149
def _add_deployment (self , deployment : Deployment ) -> Deployment :
5143
5150
import os
@@ -5365,20 +5372,27 @@ def _add_model_to_list_and_index_map(
5365
5372
self , model : dict , model_id : Optional [str ] = None
5366
5373
) -> None :
5367
5374
"""
5368
- Helper method to add a model to the model_list and update the model_id_to_deployment_index_map .
5375
+ Helper method to add a model to the model_list and update both indices .
5369
5376
5370
5377
Parameters:
5371
5378
- model: dict - the model to add to the list
5372
5379
- model_id: Optional[str] - the model ID to use for indexing. If None, will try to get from model["model_info"]["id"]
5373
5380
"""
5381
+ idx = len (self .model_list )
5374
5382
self .model_list .append (model )
5375
- # Update model index for O(1) lookup
5383
+
5384
+ # Update model_id index for O(1) lookup
5376
5385
if model_id is not None :
5377
- self .model_id_to_deployment_index_map [model_id ] = len ( self . model_list ) - 1
5386
+ self .model_id_to_deployment_index_map [model_id ] = idx
5378
5387
elif model .get ("model_info" , {}).get ("id" ) is not None :
5379
- self .model_id_to_deployment_index_map [model ["model_info" ]["id" ]] = (
5380
- len (self .model_list ) - 1
5381
- )
5388
+ self .model_id_to_deployment_index_map [model ["model_info" ]["id" ]] = idx
5389
+
5390
+ # Update model_name index for O(1) lookup
5391
+ model_name = model .get ("model_name" )
5392
+ if model_name :
5393
+ if model_name not in self .model_name_to_deployment_indices :
5394
+ self .model_name_to_deployment_indices [model_name ] = []
5395
+ self .model_name_to_deployment_indices [model_name ].append (idx )
5382
5396
5383
5397
def upsert_deployment (self , deployment : Deployment ) -> Optional [Deployment ]:
5384
5398
"""
@@ -6094,6 +6108,22 @@ async def set_response_headers(
6094
6108
additional_headers [header ] = value
6095
6109
return response
6096
6110
6111
+ def _build_model_name_index (self , model_list : list ) -> None :
6112
+ """
6113
+ Build model_name -> deployment indices mapping for O(1) lookups.
6114
+
6115
+ This index allows us to find all deployments for a given model_name in O(1) time
6116
+ instead of O(n) linear scan through the entire model_list.
6117
+ """
6118
+ self .model_name_to_deployment_indices .clear ()
6119
+
6120
+ for idx , model in enumerate (model_list ):
6121
+ model_name = model .get ("model_name" )
6122
+ if model_name :
6123
+ if model_name not in self .model_name_to_deployment_indices :
6124
+ self .model_name_to_deployment_indices [model_name ] = []
6125
+ self .model_name_to_deployment_indices [model_name ].append (idx )
6126
+
6097
6127
def _build_model_id_to_deployment_index_map (self , model_list : list ):
6098
6128
"""
6099
6129
Build model index from model list to enable O(1) lookups immediately.
@@ -6198,18 +6228,27 @@ def _get_all_deployments(
6198
6228
Used for accurate 'get_model_list'.
6199
6229
6200
6230
if team_id specified, only return team-specific models
6231
+
6232
+ Optimized with O(1) index lookup instead of O(n) linear scan.
6201
6233
"""
6202
6234
returned_models : List [DeploymentTypedDict ] = []
6203
- for model in self .model_list :
6204
- if self .should_include_deployment (
6205
- model_name = model_name , model = model , team_id = team_id
6206
- ):
6207
- if model_alias is not None :
6208
- alias_model = copy .deepcopy (model )
6209
- alias_model ["model_name" ] = model_alias
6210
- returned_models .append (alias_model )
6211
- else :
6212
- returned_models .append (model )
6235
+
6236
+ # O(1) lookup in model_name index
6237
+ if model_name in self .model_name_to_deployment_indices :
6238
+ indices = self .model_name_to_deployment_indices [model_name ]
6239
+
6240
+ # O(k) where k = deployments for this model_name (typically 1-10)
6241
+ for idx in indices :
6242
+ model = self .model_list [idx ]
6243
+ if self .should_include_deployment (
6244
+ model_name = model_name , model = model , team_id = team_id
6245
+ ):
6246
+ if model_alias is not None :
6247
+ alias_model = copy .deepcopy (model )
6248
+ alias_model ["model_name" ] = model_alias
6249
+ returned_models .append (alias_model )
6250
+ else :
6251
+ returned_models .append (model )
6213
6252
6214
6253
return returned_models
6215
6254
0 commit comments