[PD-Disagg] Improve KVManager init across all backends (#19240)
Signed-off-by: Shangming Cai <csmthu@gmail.com>
This commit is contained in:
@@ -6,8 +6,9 @@ import logging
|
|||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from collections import defaultdict
|
||||||
from functools import cache
|
from functools import cache
|
||||||
from typing import Dict, List, Optional, Tuple, Union
|
from typing import Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
@@ -107,11 +108,32 @@ class CommonKVManager(BaseKVManager):
|
|||||||
self.transfer_infos = {}
|
self.transfer_infos = {}
|
||||||
self.decode_kv_args_table = {}
|
self.decode_kv_args_table = {}
|
||||||
self.pp_group = get_pp_group()
|
self.pp_group = get_pp_group()
|
||||||
|
# If a timeout happens on the prefill side, it means prefill instances
|
||||||
|
# fail to receive the KV indices from the decode instance of this request.
|
||||||
|
# These timeout requests should be aborted to release the tree cache.
|
||||||
|
self.bootstrap_timeout = envs.SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT.get()
|
||||||
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
||||||
self.connection_pool: Dict[str, Dict[str, Union[str, int]]] = {}
|
self.connection_pool: Dict[str, Dict[str, Union[str, int]]] = {}
|
||||||
self.connection_lock = threading.Lock()
|
self.connection_lock = threading.Lock()
|
||||||
self.required_prefill_response_num_table: Dict[int, int] = {}
|
self.required_prefill_response_num_table: Dict[int, int] = {}
|
||||||
self.prefill_info_table: Dict[str, PrefillServerInfo] = {}
|
self.prefill_info_table: Dict[str, PrefillServerInfo] = {}
|
||||||
|
self.heartbeat_failures: Dict[str, int] = {}
|
||||||
|
self.session_pool: Dict = defaultdict(requests.Session)
|
||||||
|
self.session_pool_lock = threading.Lock()
|
||||||
|
self.addr_to_rooms_tracker: Dict[str, Set[int]] = defaultdict(set)
|
||||||
|
self.prefill_response_tracker: Dict[int, Set[int]] = defaultdict(set)
|
||||||
|
# Heartbeat interval should be at least 2 seconds
|
||||||
|
self.heartbeat_interval = max(
|
||||||
|
envs.SGLANG_DISAGGREGATION_HEARTBEAT_INTERVAL.get(), 2.0
|
||||||
|
)
|
||||||
|
# Heartbeat failure should be at least 1
|
||||||
|
self.max_failures = max(
|
||||||
|
envs.SGLANG_DISAGGREGATION_HEARTBEAT_MAX_FAILURE.get(), 1
|
||||||
|
)
|
||||||
|
# If a timeout happens on the decode side, it means decode instances
|
||||||
|
# fail to receive the KV Cache transfer done signal after bootstrapping.
|
||||||
|
# These timeout requests should be aborted to release the tree cache.
|
||||||
|
self.waiting_timeout = envs.SGLANG_DISAGGREGATION_WAITING_TIMEOUT.get()
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Unsupported DisaggregationMode: {self.disaggregation_mode}"
|
f"Unsupported DisaggregationMode: {self.disaggregation_mode}"
|
||||||
|
|||||||
@@ -9,11 +9,10 @@ import struct
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
import requests
|
|
||||||
|
|
||||||
from sglang.srt.disaggregation.base.conn import KVArgs, KVPoll
|
from sglang.srt.disaggregation.base.conn import KVArgs, KVPoll
|
||||||
from sglang.srt.disaggregation.common.conn import (
|
from sglang.srt.disaggregation.common.conn import (
|
||||||
@@ -206,33 +205,11 @@ class MooncakeKVManager(CommonKVManager):
|
|||||||
threading.Thread(
|
threading.Thread(
|
||||||
target=self.transfer_worker, args=(queue, executor), daemon=True
|
target=self.transfer_worker, args=(queue, executor), daemon=True
|
||||||
).start()
|
).start()
|
||||||
# If a timeout happens on the prefill side, it means prefill instances
|
|
||||||
# fail to receive the KV indices from the decode instance of this request.
|
|
||||||
# These timeout requests should be aborted to release the tree cache.
|
|
||||||
self.bootstrap_timeout = envs.SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT.get()
|
|
||||||
|
|
||||||
self.enable_custom_mem_pool, self.custom_mem_pool_type = (
|
self.enable_custom_mem_pool, self.custom_mem_pool_type = (
|
||||||
check_mooncake_custom_mem_pool_enabled()
|
check_mooncake_custom_mem_pool_enabled()
|
||||||
)
|
)
|
||||||
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
||||||
self.heartbeat_failures = {}
|
|
||||||
self.session_pool = defaultdict(requests.Session)
|
|
||||||
self.session_pool_lock = threading.Lock()
|
|
||||||
self.addr_to_rooms_tracker = defaultdict(set)
|
|
||||||
self.prefill_response_tracker: Dict[int, Set[int]] = defaultdict(set)
|
|
||||||
# Heartbeat interval should be at least 2 seconds
|
|
||||||
self.heartbeat_interval = max(
|
|
||||||
envs.SGLANG_DISAGGREGATION_HEARTBEAT_INTERVAL.get(), 2.0
|
|
||||||
)
|
|
||||||
# Heartbeat failure should be at least 1
|
|
||||||
self.max_failures = max(
|
|
||||||
envs.SGLANG_DISAGGREGATION_HEARTBEAT_MAX_FAILURE.get(), 1
|
|
||||||
)
|
|
||||||
self.start_decode_thread()
|
self.start_decode_thread()
|
||||||
# If a timeout happens on the decode side, it means decode instances
|
|
||||||
# fail to receive the KV Cache transfer done signal after bootstrapping.
|
|
||||||
# These timeout requests should be aborted to release the tree cache.
|
|
||||||
self.waiting_timeout = envs.SGLANG_DISAGGREGATION_WAITING_TIMEOUT.get()
|
|
||||||
|
|
||||||
def init_engine(self):
|
def init_engine(self):
|
||||||
self.engine = get_mooncake_transfer_engine()
|
self.engine = get_mooncake_transfer_engine()
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import os
|
|||||||
import struct
|
import struct
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from collections import defaultdict
|
from typing import Dict, List, Optional, Tuple
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
|
|
||||||
import msgspec
|
import msgspec
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -194,16 +193,8 @@ class MoriKVManager(CommonKVManager):
|
|||||||
self.transfer_lock = threading.Lock()
|
self.transfer_lock = threading.Lock()
|
||||||
self._register_local_buffers()
|
self._register_local_buffers()
|
||||||
if self.disaggregation_mode == DisaggregationMode.PREFILL:
|
if self.disaggregation_mode == DisaggregationMode.PREFILL:
|
||||||
self.bootstrap_timeout = get_int_env_var(
|
|
||||||
"SGLANG_DISAGGREGATION_BOOTSTRAP_TIMEOUT", 300
|
|
||||||
)
|
|
||||||
self._start_bootstrap_thread()
|
self._start_bootstrap_thread()
|
||||||
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
elif self.disaggregation_mode == DisaggregationMode.DECODE:
|
||||||
self.waiting_timeout = get_int_env_var(
|
|
||||||
"SGLANG_DISAGGREGATION_WAITING_TIMEOUT", 300
|
|
||||||
)
|
|
||||||
self.prefill_response_tracker: Dict[int, Set[int]] = defaultdict(set)
|
|
||||||
self.addr_to_rooms_tracker = defaultdict(set)
|
|
||||||
self.room_to_bootstrap_addr: Dict[int, str] = {}
|
self.room_to_bootstrap_addr: Dict[int, str] = {}
|
||||||
self._start_decode_thread()
|
self._start_decode_thread()
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from typing import Dict, List, Optional, Set
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import numpy.typing as npt
|
import numpy.typing as npt
|
||||||
import requests
|
|
||||||
|
|
||||||
from sglang.srt.disaggregation.base.conn import KVArgs, KVPoll
|
from sglang.srt.disaggregation.base.conn import KVArgs, KVPoll
|
||||||
from sglang.srt.disaggregation.common.conn import (
|
from sglang.srt.disaggregation.common.conn import (
|
||||||
@@ -193,21 +192,6 @@ class NixlKVManager(CommonKVManager):
|
|||||||
self.transfer_statuses: Dict[int, TransferStatus] = defaultdict(
|
self.transfer_statuses: Dict[int, TransferStatus] = defaultdict(
|
||||||
TransferStatus
|
TransferStatus
|
||||||
)
|
)
|
||||||
self.heartbeat_failures = {}
|
|
||||||
self.session_pool = defaultdict(requests.Session)
|
|
||||||
self.session_pool_lock = threading.Lock()
|
|
||||||
self.addr_to_rooms_tracker = defaultdict(set)
|
|
||||||
self.connection_lock = threading.Lock()
|
|
||||||
|
|
||||||
# Heartbeat interval should be at least 2 seconds
|
|
||||||
self.heartbeat_interval = max(
|
|
||||||
envs.SGLANG_DISAGGREGATION_HEARTBEAT_INTERVAL.get(), 2.0
|
|
||||||
)
|
|
||||||
# Heartbeat failure should be at least 1
|
|
||||||
self.max_failures = max(
|
|
||||||
envs.SGLANG_DISAGGREGATION_HEARTBEAT_MAX_FAILURE.get(), 1
|
|
||||||
)
|
|
||||||
self.waiting_timeout = envs.SGLANG_DISAGGREGATION_WAITING_TIMEOUT.get()
|
|
||||||
self._start_heartbeat_checker_thread()
|
self._start_heartbeat_checker_thread()
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|||||||
Reference in New Issue
Block a user