[Weight Cache] Support static DP/EP layouts (#33684)
Co-authored-by: siyu <liusy58@linux.alibaba.com>
This commit is contained in:
@@ -54,20 +54,24 @@ def run_single_daemon(
|
||||
"""Run a single daemon process for one (pp_rank, tp_rank)."""
|
||||
import traceback
|
||||
|
||||
from sglang.srt.server_args import ServerArgs
|
||||
from sglang.srt.weight_cache.daemon import WeightCacheDaemon
|
||||
|
||||
daemon = WeightCacheDaemon(
|
||||
server_args = ServerArgs(
|
||||
model_path=model_path,
|
||||
gpu_id=gpu_id,
|
||||
tp_size=tp_size,
|
||||
tp_rank=tp_rank,
|
||||
pp_size=pp_size,
|
||||
pp_rank=pp_rank,
|
||||
dp_size=1,
|
||||
load_format=load_format,
|
||||
dtype=dtype,
|
||||
quantization=quantization,
|
||||
trust_remote_code=trust_remote_code,
|
||||
)
|
||||
daemon = WeightCacheDaemon(
|
||||
server_args=server_args,
|
||||
gpu_id=gpu_id,
|
||||
tp_rank=tp_rank,
|
||||
pp_rank=pp_rank,
|
||||
dist_init_method=dist_init_method,
|
||||
)
|
||||
daemon.socket_path = socket_path
|
||||
|
||||
@@ -7,7 +7,7 @@ These cover the pure-Python logic that the GPU end-to-end test
|
||||
- length-prefixed socket framing (send_msg/recv_msg) over socketpair()
|
||||
- CacheConfig fingerprint matching / (de)serialization
|
||||
- quant-config hashing and method-name extraction
|
||||
- the daemon rank formula and socket/ready path derivation
|
||||
- daemon spawn configuration and socket/ready path derivation
|
||||
- the IPC quantization allowlist (the gate that keeps silently-wrong
|
||||
quant methods off the zero-copy path)
|
||||
- stale-vs-live daemon file cleanup
|
||||
@@ -21,6 +21,7 @@ import os
|
||||
import socket
|
||||
import struct
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
|
||||
import torch
|
||||
|
||||
@@ -61,6 +62,14 @@ def _make_cache_config(**overrides) -> CacheConfig:
|
||||
pp_rank=0,
|
||||
dp_size=1,
|
||||
ep_size=1,
|
||||
moe_dp_size=1,
|
||||
moe_dp_rank=0,
|
||||
moe_ep_rank=0,
|
||||
enable_dp_attention=False,
|
||||
enable_dp_lm_head=False,
|
||||
attn_cp_size=1,
|
||||
moe_dense_tp_size=None,
|
||||
moe_a2a_backend="none",
|
||||
quant_method="",
|
||||
quant_config_hash="",
|
||||
dtype="torch.float16",
|
||||
@@ -159,6 +168,11 @@ class TestCacheConfig(CustomTestCase):
|
||||
base = _make_cache_config()
|
||||
for field, value in (
|
||||
("tp_rank", 1),
|
||||
("moe_dp_rank", 1),
|
||||
("moe_ep_rank", 1),
|
||||
("enable_dp_attention", True),
|
||||
("moe_dense_tp_size", 1),
|
||||
("moe_a2a_backend", "mooncake"),
|
||||
("dtype", "torch.bfloat16"),
|
||||
("quant_method", "fp8"),
|
||||
("model_path", "/models/other"),
|
||||
@@ -250,6 +264,68 @@ class TestGlobalRankAndPaths(CustomTestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestDaemonLaunchConfiguration(CustomTestCase):
|
||||
def test_spawn_forwards_complete_server_args_without_projection(self):
|
||||
from sglang.srt.weight_cache import daemon
|
||||
|
||||
# The spawn helper receives Engine's already-resolved ServerArgs. A
|
||||
# minimal namespace keeps this projection test CPU-only and
|
||||
# model-independent; importantly, no EPLB configuration is involved.
|
||||
server_args = SimpleNamespace(
|
||||
model_path="/models/demo",
|
||||
tp_size=8,
|
||||
pp_size=1,
|
||||
dp_size=8,
|
||||
ep_size=8,
|
||||
moe_dp_size=2,
|
||||
enable_dp_attention=True,
|
||||
enable_dp_lm_head=True,
|
||||
attn_cp_size=2,
|
||||
moe_dense_tp_size=1,
|
||||
moe_a2a_backend="mooncake",
|
||||
deepep_mode="low_latency",
|
||||
load_format="safetensors",
|
||||
dtype="bfloat16",
|
||||
quantization="fp8",
|
||||
model_loader_extra_config='{"key": "value"}',
|
||||
trust_remote_code=True,
|
||||
revision="test-revision",
|
||||
)
|
||||
|
||||
class FakeProcess:
|
||||
pid = 1234
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
class FakeContext:
|
||||
def Process(self, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
return FakeProcess()
|
||||
|
||||
fake_context = FakeContext()
|
||||
from unittest import mock
|
||||
|
||||
with mock.patch.object(
|
||||
daemon.multiprocessing, "get_context", return_value=fake_context
|
||||
) as get_context:
|
||||
result = daemon.spawn_weight_cache_daemon(
|
||||
server_args,
|
||||
gpu_id=3,
|
||||
tp_rank=3,
|
||||
pp_rank=0,
|
||||
dist_init_method="tcp://127.0.0.1:29500",
|
||||
)
|
||||
|
||||
get_context.assert_called_once_with("spawn")
|
||||
self.assertIsInstance(result, FakeProcess)
|
||||
self.assertIs(fake_context.kwargs["target"], daemon.run_weight_cache_daemon)
|
||||
self.assertEqual(
|
||||
fake_context.kwargs["args"],
|
||||
(server_args, 3, 3, 0, "tcp://127.0.0.1:29500"),
|
||||
)
|
||||
|
||||
|
||||
class TestIpcQuantAllowlist(CustomTestCase):
|
||||
def test_unquantized_is_supported(self):
|
||||
self.assertTrue(is_ipc_quant_supported("", None))
|
||||
|
||||
@@ -179,6 +179,22 @@ _EXPOSED = {
|
||||
("utils/common.py", "speculative_num_draft_tokens"),
|
||||
("utils/common.py", "speculative_num_steps"),
|
||||
("utils/hf_transformers/processor.py", "image_processor_backend"),
|
||||
# The daemon command and constructor snapshot the resolved startup layout
|
||||
# before the daemon's loading lifecycle can apply any runtime overrides.
|
||||
("weight_cache/daemon.py", "attn_cp_size"),
|
||||
("weight_cache/daemon.py", "deepep_mode"),
|
||||
("weight_cache/daemon.py", "dp_size"),
|
||||
("weight_cache/daemon.py", "dtype"),
|
||||
("weight_cache/daemon.py", "enable_dp_attention"),
|
||||
("weight_cache/daemon.py", "enable_dp_lm_head"),
|
||||
("weight_cache/daemon.py", "ep_size"),
|
||||
("weight_cache/daemon.py", "load_format"),
|
||||
("weight_cache/daemon.py", "model_path"),
|
||||
("weight_cache/daemon.py", "moe_a2a_backend"),
|
||||
("weight_cache/daemon.py", "moe_dense_tp_size"),
|
||||
("weight_cache/daemon.py", "moe_dp_size"),
|
||||
("weight_cache/daemon.py", "pp_size"),
|
||||
("weight_cache/daemon.py", "quantization"),
|
||||
}
|
||||
|
||||
# Pairs whose resolution write only happens on a CUDA host (capability or
|
||||
@@ -196,6 +212,11 @@ _OVERRIDDEN_AND_READ = {
|
||||
("dllm/config.py", "model_path"),
|
||||
("entrypoints/engine.py", "reasoning_parser"),
|
||||
("entrypoints/engine.py", "tool_call_parser"),
|
||||
("weight_cache/daemon.py", "dp_size"),
|
||||
("weight_cache/daemon.py", "dtype"),
|
||||
("weight_cache/daemon.py", "ep_size"),
|
||||
("weight_cache/daemon.py", "load_format"),
|
||||
("weight_cache/daemon.py", "model_path"),
|
||||
("configs/model_config.py", "dtype"),
|
||||
("configs/model_config.py", "model_path"),
|
||||
("mem_cache/kv_cache_builder.py", "hicache_storage_backend"),
|
||||
|
||||
Reference in New Issue
Block a user