@@ -370,13 +370,7 @@ def _install_stubs():
370370
371371_install_stubs ()
372372
373- import ucm .integration .vllm .hma_connector as hma_connector_module
374373import ucm .integration .vllm .ucm_connector as ucm_connector_module
375- from ucm .integration .vllm .hma_connector import (
376- FAWARequestDispatchMeta ,
377- UCMFAWAConnector ,
378- UCMFAWAConnectorMetadata ,
379- )
380374from ucm .integration .vllm .metrics import UCMConnectorStats , UCMPromMetrics
381375from ucm .integration .vllm .ucm_connector import (
382376 PendingDumpTask ,
@@ -482,38 +476,6 @@ def _reset_fakes():
482476 dispatcher_module ._DISPATCHER = None
483477
484478
485- class FakeHMAStore :
486- def __init__ (self , label , fail_wait = False ):
487- self .label = label
488- self .fail_wait = fail_wait
489- self .loaded = []
490- self .dumped = []
491- self .waited = []
492-
493- def load_data (self , keys , shard_indices , ptrs ):
494- task = f"{ self .label } -load-{ len (keys )} -{ len (self .loaded )} "
495- self .loaded .append ((list (keys ), list (shard_indices ), ptrs , task ))
496- return task
497-
498- def dump_data (self , keys , shard_indices , ptrs , event_handle ):
499- task = f"{ self .label } -dump-{ len (keys )} -{ len (self .dumped )} "
500- self .dumped .append ((list (keys ), list (shard_indices ), ptrs , event_handle , task ))
501- return task
502-
503- def wait (self , task ):
504- self .waited .append (task )
505- if self .fail_wait :
506- raise RuntimeError (f"{ self .label } wait failed" )
507-
508-
509- class FakeHMADevice :
510- def __init__ (self ):
511- self .destroyed = []
512-
513- def destroy_event_handle (self , event_handle ):
514- self .destroyed .append (event_handle )
515-
516-
517479def test_config_definitions_register_enable_list_and_metric_names ():
518480 _reset_fakes ()
519481 config = _metrics_config ()
@@ -1023,219 +985,6 @@ def destroy_event_handle(self, event_handle):
1023985 ]
1024986
1025987
1026- def _fawa_request (load_keys = None , dump_keys = None ):
1027- return FAWARequestDispatchMeta (
1028- load_keys = list (load_keys or []),
1029- load_hash_start = 0 ,
1030- load_hash_end = len (load_keys or []),
1031- load_vllm_block_ids = ([1 , 2 ],),
1032- dump_keys = list (dump_keys or []),
1033- dump_hash_start = 0 ,
1034- dump_hash_end = len (dump_keys or []),
1035- dump_vllm_block_ids = ([1 , 2 ],),
1036- )
1037-
1038-
1039- def _new_hma_connector (metadata , fa_store = None , wa_store = None ):
1040- connector = object .__new__ (UCMFAWAConnector )
1041- connector .fa_store = fa_store or FakeHMAStore ("FA" )
1042- connector .wa_store = wa_store or FakeHMAStore ("WA" )
1043- connector ._fawa_store_block_sizes = {"FA" : 100 , "WA" : 20 }
1044- connector ._invalid_block_ids = set ()
1045- connector .tp_size = 1
1046- connector .tp_rank = 0
1047- connector .wa_dump_block_wise = True
1048- connector .fa_group_ids = set ()
1049- connector .window_group_ids = set ()
1050- connector .group_metas = []
1051- connector .tp_dump_tasks = {}
1052- connector ._direct_task_has_load = False
1053- connector ._direct_task_load_duration_ms = 0.0
1054- connector ._direct_task_compute_start_ms = None
1055- connector .device = FakeHMADevice ()
1056- connector ._get_connector_metadata = lambda : metadata
1057- connector ._extract_fa_ptr = lambda * args , ** kwargs : [[0 ], [0 ]]
1058- connector ._extract_wa_ptr = lambda * args , ** kwargs : [[0 ], [0 ]]
1059- return connector
1060-
1061-
1062- def test_hma_connector_records_load_metrics (monkeypatch ):
1063- _reset_fakes ()
1064- times = iter ([1.0 , 1.1 , 1.11 ])
1065- monkeypatch .setattr (
1066- hma_connector_module .time ,
1067- "perf_counter" ,
1068- lambda : next (times ),
1069- )
1070- metadata = UCMFAWAConnectorMetadata (
1071- request_meta = {"req-1" : _fawa_request (load_keys = [b"a" , b"b" ])}
1072- )
1073- connector = _new_hma_connector (metadata )
1074-
1075- connector .start_load_kv (None )
1076-
1077- stats = fake_ucmmetrics .updated [- 1 ]
1078- assert stats ["load_requests_num" ] == 1
1079- assert stats ["load_blocks_num" ] == 3
1080- assert stats ["load_duration" ] == pytest .approx (100.0 )
1081- assert stats ["load_bytes_total" ] == 220
1082- assert stats ["load_speed" ] == pytest .approx (220 / 100 / 1024 / 1024 )
1083- assert connector ._direct_task_has_load is True
1084- assert connector ._direct_task_load_duration_ms == pytest .approx (100.0 )
1085- assert connector ._direct_task_compute_start_ms == pytest .approx (1110.0 )
1086-
1087-
1088- def test_hma_connector_load_metrics_ignore_wait_failure_for_counting (monkeypatch ):
1089- _reset_fakes ()
1090- times = iter ([1.0 , 1.1 , 1.11 ])
1091- monkeypatch .setattr (
1092- hma_connector_module .time ,
1093- "perf_counter" ,
1094- lambda : next (times ),
1095- )
1096- metadata = UCMFAWAConnectorMetadata (
1097- request_meta = {"req-1" : _fawa_request (load_keys = [b"a" , b"b" ])}
1098- )
1099- connector = _new_hma_connector (metadata , wa_store = FakeHMAStore ("WA" , True ))
1100-
1101- connector .start_load_kv (None )
1102-
1103- stats = fake_ucmmetrics .updated [- 1 ]
1104- assert stats ["load_requests_num" ] == 1
1105- assert stats ["load_blocks_num" ] == 3
1106- assert stats ["load_bytes_total" ] == 220
1107- assert stats ["load_speed" ] == pytest .approx (220 / 100 / 1024 / 1024 )
1108- assert connector ._invalid_block_ids == {1 , 2 }
1109-
1110-
1111- @pytest .mark .parametrize ("drain_method" , ["get_finished" , "preemption" ])
1112- def test_hma_connector_records_mixed_fa_wa_save_completion_metrics (
1113- monkeypatch , drain_method
1114- ):
1115- _reset_fakes ()
1116- times = iter ([1.0 , 1.01 , 1.02 , 1.10 , 1.12 , 1.13 , 1.15 ])
1117- monkeypatch .setattr (
1118- hma_connector_module .time ,
1119- "perf_counter" ,
1120- lambda : next (times ),
1121- )
1122- metadata = UCMFAWAConnectorMetadata (
1123- request_meta = {"req-1" : _fawa_request (dump_keys = [b"a" , b"b" ])}
1124- )
1125- connector = _new_hma_connector (metadata )
1126- handles = iter ([11 , 12 ])
1127- connector ._get_dump_event_handle = lambda : next (handles )
1128- connector ._direct_task_has_load = True
1129- connector ._direct_task_load_duration_ms = 10.0
1130- connector ._direct_task_compute_start_ms = 900.0
1131-
1132- connector .wait_for_save ()
1133-
1134- assert fake_ucmmetrics .updated == [
1135- {
1136- "save_requests_num" : 1 ,
1137- "save_blocks_num" : 4 ,
1138- "save_bytes_total" : 240 ,
1139- }
1140- ]
1141- if drain_method == "get_finished" :
1142- connector .get_finished ({"req-1" })
1143- else :
1144- connector .handle_preemptions (
1145- UCMFAWAConnectorMetadata (preempted_req_ids = {"req-1" })
1146- )
1147-
1148- assert fake_ucmmetrics .updated [1 ] == {
1149- "save_duration" : pytest .approx (110.0 ),
1150- "save_speed" : pytest .approx (200 / 110 / 1024 / 1024 ),
1151- "save_completion_wait_duration" : pytest .approx (20.0 ),
1152- "save_completion_wait_speed" : pytest .approx (200 / 20 / 1024 / 1024 ),
1153- }
1154- assert fake_ucmmetrics .updated [2 ] == {
1155- "connector_task_load_stage_load_dump_ms" : 10.0 ,
1156- "connector_task_compute_stage_load_dump_ms" : pytest .approx (100.0 ),
1157- "connector_task_dump_stage_load_dump_ms" : pytest .approx (110.0 ),
1158- "connector_task_total_load_dump_ms" : pytest .approx (220.0 ),
1159- }
1160- assert fake_ucmmetrics .updated [3 ] == {
1161- "save_duration" : pytest .approx (130.0 ),
1162- "save_speed" : pytest .approx (40 / 130 / 1024 / 1024 ),
1163- "save_completion_wait_duration" : pytest .approx (20.0 ),
1164- "save_completion_wait_speed" : pytest .approx (40 / 20 / 1024 / 1024 ),
1165- }
1166- assert fake_ucmmetrics .updated [4 ] == {
1167- "connector_task_load_stage_load_dump_ms" : 10.0 ,
1168- "connector_task_compute_stage_load_dump_ms" : pytest .approx (100.0 ),
1169- "connector_task_dump_stage_load_dump_ms" : pytest .approx (130.0 ),
1170- "connector_task_total_load_dump_ms" : pytest .approx (240.0 ),
1171- }
1172- assert connector .device .destroyed == [11 , 12 ]
1173- assert connector .tp_dump_tasks == {}
1174-
1175-
1176- def test_hma_connector_save_metrics_count_only_submitted_requests_without_changing_tp_keys (
1177- monkeypatch ,
1178- ):
1179- _reset_fakes ()
1180- times = iter ([1.0 , 1.01 , 1.02 ])
1181- monkeypatch .setattr (
1182- hma_connector_module .time ,
1183- "perf_counter" ,
1184- lambda : next (times ),
1185- )
1186- metadata = UCMFAWAConnectorMetadata (
1187- request_meta = {
1188- "req-no-rank-work" : _fawa_request (dump_keys = [b"a" ]),
1189- "req-rank-work" : _fawa_request (dump_keys = [b"b" , b"c" ]),
1190- }
1191- )
1192- connector = _new_hma_connector (metadata )
1193- connector .tp_size = 2
1194- connector .tp_rank = 0
1195- handles = iter ([11 , 12 ])
1196- connector ._get_dump_event_handle = lambda : next (handles )
1197-
1198- connector .wait_for_save ()
1199-
1200- assert list (connector .tp_dump_tasks ) == [("req-no-rank-work" , "req-rank-work" )]
1201- assert fake_ucmmetrics .updated == [
1202- {
1203- "save_requests_num" : 1 ,
1204- "save_blocks_num" : 2 ,
1205- "save_bytes_total" : 120 ,
1206- }
1207- ]
1208-
1209-
1210- def test_hma_connector_no_dump_records_load_only_breakdown (monkeypatch ):
1211- _reset_fakes ()
1212- times = iter ([1.0 ])
1213- monkeypatch .setattr (
1214- hma_connector_module .time ,
1215- "perf_counter" ,
1216- lambda : next (times ),
1217- )
1218- metadata = UCMFAWAConnectorMetadata (
1219- request_meta = {"req-1" : _fawa_request (load_keys = [b"a" ])}
1220- )
1221- connector = _new_hma_connector (metadata )
1222- connector ._direct_task_has_load = True
1223- connector ._direct_task_load_duration_ms = 7.0
1224- connector ._direct_task_compute_start_ms = 900.0
1225-
1226- connector .wait_for_save ()
1227-
1228- task_stats = fake_ucmmetrics .updated [- 1 ]
1229- assert task_stats ["connector_task_load_stage_load_only_ms" ] == 7.0
1230- assert task_stats ["connector_task_compute_stage_load_only_ms" ] == pytest .approx (
1231- 100.0
1232- )
1233- assert task_stats ["connector_task_total_load_only_ms" ] == pytest .approx (107.0 )
1234- assert connector ._direct_task_has_load is False
1235- assert connector ._direct_task_load_duration_ms == 0.0
1236- assert connector ._direct_task_compute_start_ms is None
1237-
1238-
1239988def test_multiproc_logger_uses_prefix_and_dispatcher_snapshot (tmp_path ):
1240989 _reset_fakes ()
1241990 import ucm .observability as observability
0 commit comments