feat: sync npu nightly test improvements from Ascend testcases (#29403)
This commit is contained in:
@@ -45,6 +45,21 @@ MAX_SERVER_KEEP_ALIVE_TIME = 3600
|
||||
|
||||
ACCURACY_TOLERANCE = 0.99
|
||||
|
||||
# Dataset total question counts and allowed fluctuation (in questions)
|
||||
DATASET_QUESTION_COUNTS = {
|
||||
"aime25": 30,
|
||||
"aime26": 30,
|
||||
"gpqa_diamond": 198,
|
||||
}
|
||||
|
||||
DATASET_FLUCTUATION = {
|
||||
"aime25": 2,
|
||||
"aime26": 2,
|
||||
"gpqa_diamond": 5,
|
||||
}
|
||||
|
||||
MAX_RETRY_COUNT = 3
|
||||
|
||||
SERVER_INITIALIZATION_DELAY = 120
|
||||
|
||||
if os.environ.get("ASCEND_RT_VISIBLE_DEVICES"):
|
||||
@@ -58,6 +73,31 @@ else:
|
||||
DEFAULT_URL_FOR_TEST = f"http://127.0.0.1:{DEFAULT_SERVER_PORT_FOR_TEST + 66}"
|
||||
|
||||
|
||||
def get_accuracy_threshold(datasets, baseline_accuracy):
|
||||
"""Calculate accuracy threshold based on dataset fluctuation tolerance.
|
||||
|
||||
For datasets with defined fluctuation (aime*, gpqa_diamond), use absolute
|
||||
question count tolerance. For others (e.g. mmmu), use percentage tolerance.
|
||||
"""
|
||||
dataset = datasets[0] if datasets else None
|
||||
if dataset in DATASET_FLUCTUATION and dataset in DATASET_QUESTION_COUNTS:
|
||||
fluctuation = DATASET_FLUCTUATION[dataset] / DATASET_QUESTION_COUNTS[dataset]
|
||||
return baseline_accuracy - fluctuation
|
||||
return baseline_accuracy * ACCURACY_TOLERANCE
|
||||
|
||||
|
||||
def get_max_retries(datasets):
|
||||
"""Return max retry count for accuracy tests.
|
||||
|
||||
gpqa and aime datasets support up to MAX_RETRY_COUNT retries.
|
||||
mmmu and others use 1 attempt (no retry).
|
||||
"""
|
||||
dataset = datasets[0] if datasets else None
|
||||
if dataset in DATASET_FLUCTUATION:
|
||||
return MAX_RETRY_COUNT
|
||||
return 1
|
||||
|
||||
|
||||
def run_evalscope(
|
||||
host,
|
||||
port,
|
||||
@@ -212,6 +252,7 @@ def assert_metrics(self, metrics):
|
||||
raise Exception("No metrics obtained from benchmark")
|
||||
|
||||
if self.accuracy is not None:
|
||||
threshold = get_accuracy_threshold(self.datasets, self.accuracy)
|
||||
dump_metric(
|
||||
"accuracy",
|
||||
float(metrics["accuracy"]),
|
||||
@@ -224,14 +265,11 @@ def assert_metrics(self, metrics):
|
||||
)
|
||||
self.assertGreaterEqual(
|
||||
float(metrics["accuracy"]),
|
||||
self.accuracy * ACCURACY_TOLERANCE,
|
||||
f"Accuracy check failed. Expected >= {self.accuracy * ACCURACY_TOLERANCE}, Got: {metrics['accuracy']}",
|
||||
threshold,
|
||||
f"Accuracy check failed. Expected >= {threshold}, Got: {metrics['accuracy']}",
|
||||
)
|
||||
|
||||
|
||||
MMMU_LOCAL_PATH = "/root/.cache/modelscope/hub/datasets/AI-ModelScope___mmmu"
|
||||
|
||||
|
||||
class TestNpuAccuracyTestCaseBase(CustomTestCase):
|
||||
model = None
|
||||
benchmark_tool = BENCHMARK_TOOL_DEFAULT
|
||||
@@ -249,6 +287,7 @@ class TestNpuAccuracyTestCaseBase(CustomTestCase):
|
||||
server_timeout = DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH
|
||||
envs = None
|
||||
max_attempts = 2
|
||||
n_runs = 3
|
||||
accuracy = 0.1
|
||||
|
||||
@classmethod
|
||||
@@ -280,29 +319,67 @@ class TestNpuAccuracyTestCaseBase(CustomTestCase):
|
||||
except Exception as e:
|
||||
logger.error(f"Error during tearDown: {e}")
|
||||
|
||||
def _get_dataset_args(self):
|
||||
if "mmmu" in self.datasets:
|
||||
base_args = {"mmmu": {"dataset_id": MMMU_LOCAL_PATH}}
|
||||
if self.dataset_args:
|
||||
if isinstance(self.dataset_args, dict):
|
||||
base_args.update(self.dataset_args)
|
||||
elif isinstance(self.dataset_args, str):
|
||||
base_args.update(json.loads(self.dataset_args))
|
||||
return base_args
|
||||
return self.dataset_args
|
||||
|
||||
def run_accuracy(self):
|
||||
parsed_url = urlparse(self.base_url)
|
||||
host = parsed_url.hostname
|
||||
port = parsed_url.port
|
||||
if self.benchmark_tool == EVALSCOPE:
|
||||
model_name = os.path.basename(self.model)
|
||||
max_retries = get_max_retries(self.datasets)
|
||||
best_metrics = None
|
||||
for attempt in range(max_retries):
|
||||
metrics = run_evalscope(
|
||||
host=host,
|
||||
port=port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self.dataset_args,
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
dataset_dir=self.dataset_dir,
|
||||
stream=self.stream,
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
if best_metrics is None or float(metrics.get("accuracy", 0)) > float(
|
||||
best_metrics.get("accuracy", 0)
|
||||
):
|
||||
best_metrics = metrics
|
||||
threshold = get_accuracy_threshold(self.datasets, self.accuracy)
|
||||
if float(best_metrics.get("accuracy", 0)) >= threshold:
|
||||
break
|
||||
if attempt < max_retries - 1:
|
||||
logger.info(
|
||||
f"Accuracy {best_metrics.get('accuracy')} below threshold "
|
||||
f"{threshold}, retrying ({attempt + 1}/{max_retries - 1})..."
|
||||
)
|
||||
assert_metrics(self, best_metrics)
|
||||
|
||||
def run_accuracy_multiple(self, n_runs=None):
|
||||
if n_runs is None:
|
||||
n_runs = self.n_runs
|
||||
|
||||
parsed_url = urlparse(self.base_url)
|
||||
host = parsed_url.hostname
|
||||
port = parsed_url.port
|
||||
|
||||
if self.benchmark_tool != EVALSCOPE:
|
||||
raise Exception(
|
||||
"run_accuracy_multiple only supports evalscope benchmark tool"
|
||||
)
|
||||
|
||||
model_name = os.path.basename(self.model)
|
||||
all_metrics = []
|
||||
|
||||
for i in range(n_runs):
|
||||
logger.info(f"=== Accuracy run {i + 1}/{n_runs} ===")
|
||||
metrics = run_evalscope(
|
||||
host=host,
|
||||
port=port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self._get_dataset_args(),
|
||||
dataset_args=self.dataset_args,
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
@@ -311,7 +388,34 @@ class TestNpuAccuracyTestCaseBase(CustomTestCase):
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
assert_metrics(self, metrics)
|
||||
all_metrics.append(metrics)
|
||||
if metrics and "accuracy" in metrics:
|
||||
logger.info(f"Run {i + 1} accuracy: {metrics['accuracy']}")
|
||||
else:
|
||||
logger.warning(f"Run {i + 1} failed to get accuracy metric")
|
||||
|
||||
valid_metrics = [m for m in all_metrics if m and "accuracy" in m]
|
||||
if not valid_metrics:
|
||||
raise Exception("No valid accuracy metrics obtained from any run")
|
||||
|
||||
avg_accuracy = sum(float(m["accuracy"]) for m in valid_metrics) / len(
|
||||
valid_metrics
|
||||
)
|
||||
|
||||
logger.info("=" * 60)
|
||||
logger.info("Multiple Run Accuracy Results:")
|
||||
for i, m in enumerate(valid_metrics):
|
||||
logger.info(f" Run {i + 1}: {m['accuracy']}")
|
||||
logger.info(f" Average: {avg_accuracy}")
|
||||
logger.info("=" * 60)
|
||||
|
||||
avg_metrics = {"accuracy": avg_accuracy}
|
||||
dump_metric(
|
||||
"accuracy_avg",
|
||||
avg_accuracy,
|
||||
labels={"test_case": self.__class__.__name__, "type": "accuracy"},
|
||||
)
|
||||
assert_metrics(self, avg_metrics)
|
||||
|
||||
|
||||
class TestNpuAccuracyMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
@@ -378,17 +482,6 @@ class TestNpuAccuracyMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
)
|
||||
time.sleep(MAX_SERVER_KEEP_ALIVE_TIME)
|
||||
|
||||
def _get_dataset_args(self):
|
||||
if "mmmu" in self.datasets:
|
||||
base_args = {"mmmu": {"dataset_id": MMMU_LOCAL_PATH}}
|
||||
if self.dataset_args:
|
||||
if isinstance(self.dataset_args, dict):
|
||||
base_args.update(self.dataset_args)
|
||||
elif isinstance(self.dataset_args, str):
|
||||
base_args.update(json.loads(self.dataset_args))
|
||||
return base_args
|
||||
return self.dataset_args
|
||||
|
||||
@check_role(allowed_roles=["master", "worker"])
|
||||
def run_accuracy(self):
|
||||
parsed_url = urlparse(self.base_url)
|
||||
@@ -396,21 +489,36 @@ class TestNpuAccuracyMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
port = parsed_url.port
|
||||
if self.benchmark_tool == EVALSCOPE:
|
||||
model_name = os.path.basename(self.model_config.get("model_path"))
|
||||
metrics = run_evalscope(
|
||||
host=self.host,
|
||||
port=self.port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self._get_dataset_args(),
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
dataset_dir=self.dataset_dir,
|
||||
stream=self.stream,
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
assert_metrics(self, metrics)
|
||||
max_retries = get_max_retries(self.datasets)
|
||||
best_metrics = None
|
||||
for attempt in range(max_retries):
|
||||
metrics = run_evalscope(
|
||||
host=self.host,
|
||||
port=self.port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self.dataset_args,
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
dataset_dir=self.dataset_dir,
|
||||
stream=self.stream,
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
if best_metrics is None or float(metrics.get("accuracy", 0)) > float(
|
||||
best_metrics.get("accuracy", 0)
|
||||
):
|
||||
best_metrics = metrics
|
||||
threshold = get_accuracy_threshold(self.datasets, self.accuracy)
|
||||
if float(best_metrics.get("accuracy", 0)) >= threshold:
|
||||
break
|
||||
if attempt < max_retries - 1:
|
||||
logger.info(
|
||||
f"Accuracy {best_metrics.get('accuracy')} below threshold "
|
||||
f"{threshold}, retrying ({attempt + 1}/{max_retries - 1})..."
|
||||
)
|
||||
assert_metrics(self, best_metrics)
|
||||
|
||||
|
||||
class TestNpuAccuracyMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
@@ -490,17 +598,6 @@ class TestNpuAccuracyMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
f"Sglang process exited on node {cls.host} {cls.hostname} with exit code: {exit_code}"
|
||||
)
|
||||
|
||||
def _get_dataset_args(self):
|
||||
if "mmmu" in self.datasets:
|
||||
base_args = {"mmmu": {"dataset_id": MMMU_LOCAL_PATH}}
|
||||
if self.dataset_args:
|
||||
if isinstance(self.dataset_args, dict):
|
||||
base_args.update(self.dataset_args)
|
||||
elif isinstance(self.dataset_args, str):
|
||||
base_args.update(json.loads(self.dataset_args))
|
||||
return base_args
|
||||
return self.dataset_args
|
||||
|
||||
@check_role(allowed_roles=["router"])
|
||||
def run_accuracy(self):
|
||||
parsed_url = urlparse(self.base_url)
|
||||
@@ -508,18 +605,33 @@ class TestNpuAccuracyMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
port = parsed_url.port
|
||||
if self.benchmark_tool == EVALSCOPE:
|
||||
model_name = os.path.basename(self.model_config.get("model_path"))
|
||||
metrics = run_evalscope(
|
||||
host=host,
|
||||
port=port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self._get_dataset_args(),
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
dataset_dir=self.dataset_dir,
|
||||
stream=self.stream,
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
assert_metrics(self, metrics)
|
||||
max_retries = get_max_retries(self.datasets)
|
||||
best_metrics = None
|
||||
for attempt in range(max_retries):
|
||||
metrics = run_evalscope(
|
||||
host=host,
|
||||
port=port,
|
||||
model=model_name,
|
||||
datasets=self.datasets,
|
||||
dataset_args=self.dataset_args,
|
||||
eval_batch_size=self.eval_batch_size,
|
||||
limit=self.limit,
|
||||
generation_config=self.generation_config,
|
||||
dataset_dir=self.dataset_dir,
|
||||
stream=self.stream,
|
||||
timeout=self.timeout,
|
||||
eval_type=self.eval_type,
|
||||
)
|
||||
if best_metrics is None or float(metrics.get("accuracy", 0)) > float(
|
||||
best_metrics.get("accuracy", 0)
|
||||
):
|
||||
best_metrics = metrics
|
||||
threshold = get_accuracy_threshold(self.datasets, self.accuracy)
|
||||
if float(best_metrics.get("accuracy", 0)) >= threshold:
|
||||
break
|
||||
if attempt < max_retries - 1:
|
||||
logger.info(
|
||||
f"Accuracy {best_metrics.get('accuracy')} below threshold "
|
||||
f"{threshold}, retrying ({attempt + 1}/{max_retries - 1})..."
|
||||
)
|
||||
assert_metrics(self, best_metrics)
|
||||
|
||||
@@ -24,6 +24,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
NAMESPACE = os.environ.get("NAMESPACE")
|
||||
CONFIGMAP_NAME = os.environ.get("KUBE_CONFIG_MAP")
|
||||
ACTIVE_TEST_CLASS = "active-test-class"
|
||||
|
||||
LOCAL_TIMEOUT = 3600
|
||||
ALL_ROLE_SET = {"prefill", "decode", "router", "master", "worker"}
|
||||
@@ -41,6 +42,7 @@ BOOTSTRAP_INIT_PORT = 8995
|
||||
# Timeouts and delays
|
||||
ROUTER_CONFIGMAP_TIMEOUT = 300
|
||||
SERVER_INITIALIZATION_DELAY = 30
|
||||
SERVICE_EXIT_WAIT_SECONDS = 120
|
||||
|
||||
|
||||
def get_nic_name():
|
||||
@@ -190,6 +192,65 @@ def query_configmap(name, namespace):
|
||||
return None
|
||||
|
||||
|
||||
def upsert_configmap_field_strict(
|
||||
name: str,
|
||||
namespace: str,
|
||||
key: str,
|
||||
value: str,
|
||||
):
|
||||
"""
|
||||
Add or update a field in ConfigMap using patch.
|
||||
Strict mode: fail if ConfigMap does not exist.
|
||||
"""
|
||||
from kubernetes.client.rest import ApiException
|
||||
|
||||
k8s_api = get_k8s_api()
|
||||
patch = {"data": {key: value}}
|
||||
|
||||
try:
|
||||
k8s_api.patch_namespaced_config_map(name=name, namespace=namespace, body=patch)
|
||||
logger.info(f"Upserted ConfigMap {name}: {key}={value}")
|
||||
except ApiException as e:
|
||||
if e.status == 404:
|
||||
raise RuntimeError(
|
||||
f"ConfigMap {name} does not exist in namespace {namespace}"
|
||||
)
|
||||
logger.error(f"Failed to upsert ConfigMap {name}: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def wait_for_prefill_decode_exit(
|
||||
key: str,
|
||||
value: str,
|
||||
timeout: int = ROUTER_CONFIGMAP_TIMEOUT,
|
||||
poll_interval: int = 15,
|
||||
):
|
||||
start_time = time.time()
|
||||
|
||||
while time.time() - start_time < timeout:
|
||||
configmap = query_configmap(CONFIGMAP_NAME, NAMESPACE)
|
||||
if not configmap or not configmap.data:
|
||||
logger.info(f"ConfigMap data is not available yet, waiting for 15s...")
|
||||
time.sleep(poll_interval)
|
||||
continue
|
||||
|
||||
existing_value = configmap.data.get(key)
|
||||
|
||||
upsert_configmap_field_strict(CONFIGMAP_NAME, NAMESPACE, key, value)
|
||||
|
||||
if existing_value is not None:
|
||||
logger.info(
|
||||
"%s already set (%s), waiting 120s for prefill/decode to exit ...",
|
||||
key,
|
||||
existing_value,
|
||||
)
|
||||
time.sleep(SERVICE_EXIT_WAIT_SECONDS)
|
||||
else:
|
||||
logger.info("%s set for the first time (%s)", key, value)
|
||||
|
||||
return
|
||||
|
||||
|
||||
# Get node count from Kubernetes
|
||||
def discover_worker_nodes():
|
||||
"""Discover worker nodes from Kubernetes.
|
||||
|
||||
@@ -15,11 +15,16 @@ from sglang.test.ascend.e2e.gen_dataset_fixed_len import (
|
||||
save_jsonl,
|
||||
)
|
||||
from sglang.test.ascend.e2e.test_npu_multi_node_utils import (
|
||||
ACTIVE_TEST_CLASS,
|
||||
CONFIGMAP_NAME,
|
||||
NAMESPACE,
|
||||
SERVICE_PORT,
|
||||
check_role,
|
||||
launch_pd_mix_node,
|
||||
launch_pd_separation_node,
|
||||
launch_router,
|
||||
query_configmap,
|
||||
wait_for_prefill_decode_exit,
|
||||
wait_server_ready,
|
||||
)
|
||||
from sglang.test.test_utils import (
|
||||
@@ -338,6 +343,7 @@ def run_bench_serving(
|
||||
repeat_rate=None,
|
||||
temperature=None,
|
||||
top_p=None,
|
||||
env=None,
|
||||
):
|
||||
metrics_path = os.getenv("METRICS_DATA_FILE")
|
||||
result_file = (
|
||||
@@ -449,7 +455,12 @@ def run_bench_serving(
|
||||
metrics = {"mean_ttft": None, "mean_tpot": None, "total_tps": None}
|
||||
|
||||
process = subprocess.Popen(
|
||||
cmd_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1
|
||||
cmd_args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
env=env,
|
||||
)
|
||||
try:
|
||||
# Read output line by line
|
||||
@@ -883,6 +894,7 @@ class TestNpuPerformanceTestCaseBase(CustomTestCase):
|
||||
|
||||
dp = None
|
||||
generation_kwargs = None
|
||||
pop_sglang_is_in_ci_for_gsp = False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -961,7 +973,15 @@ class TestNpuPerformanceTestCaseBase(CustomTestCase):
|
||||
"top_p": self.top_p,
|
||||
}
|
||||
logger.info(f"Starting benchmark with parameters: {bench_params}")
|
||||
metrics = run_bench_serving(**bench_params)
|
||||
if (
|
||||
self.dataset_name == "generated-shared-prefix"
|
||||
and self.pop_sglang_is_in_ci_for_gsp
|
||||
):
|
||||
bench_env = os.environ.copy()
|
||||
bench_env.pop("SGLANG_IS_IN_CI", None)
|
||||
else:
|
||||
bench_env = None
|
||||
metrics = run_bench_serving(**bench_params, env=bench_env)
|
||||
assert_metrics(self, metrics)
|
||||
|
||||
|
||||
@@ -993,6 +1013,7 @@ class TestNpuPerfMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
|
||||
dp = None
|
||||
generation_kwargs = None
|
||||
pop_sglang_is_in_ci_for_gsp = False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -1085,7 +1106,15 @@ class TestNpuPerfMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
"top_p": self.top_p,
|
||||
}
|
||||
logger.info(f"Starting benchmark with parameters: {bench_params}")
|
||||
metrics = run_bench_serving(**bench_params)
|
||||
if (
|
||||
self.dataset_name == "generated-shared-prefix"
|
||||
and self.pop_sglang_is_in_ci_for_gsp
|
||||
):
|
||||
bench_env = os.environ.copy()
|
||||
bench_env.pop("SGLANG_IS_IN_CI", None)
|
||||
else:
|
||||
bench_env = None
|
||||
metrics = run_bench_serving(**bench_params, env=bench_env)
|
||||
assert_metrics(self, metrics)
|
||||
|
||||
|
||||
@@ -1117,6 +1146,7 @@ class TestNpuPerfMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
|
||||
dp = None
|
||||
generation_kwargs = None
|
||||
pop_sglang_is_in_ci_for_gsp = False
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -1138,15 +1168,25 @@ class TestNpuPerfMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
logger.info("Start exec tearDownClass")
|
||||
if cls.process:
|
||||
try:
|
||||
kill_process_tree(cls.process.pid)
|
||||
for _ in range(60):
|
||||
if cls.process.poll() is not None:
|
||||
logger.info("Process fully exited")
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
logger.warning("Process did NOT exit in time")
|
||||
except Exception as e:
|
||||
logger.error(f"Error during tearDown: {e}")
|
||||
logger.info("tearDownClass finished")
|
||||
|
||||
@classmethod
|
||||
@check_role(allowed_roles=["router"])
|
||||
def start_router_server(cls):
|
||||
wait_for_prefill_decode_exit(key=ACTIVE_TEST_CLASS, value=cls.__name__)
|
||||
logger.info(f"Starting router in thread...")
|
||||
sglang_thread = threading.Thread(target=launch_router, args=(cls.model_config,))
|
||||
sglang_thread.daemon = True
|
||||
@@ -1170,6 +1210,13 @@ class TestNpuPerfMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
|
||||
# Loop to check if the process is still running
|
||||
while True:
|
||||
configmap = query_configmap(CONFIGMAP_NAME, NAMESPACE)
|
||||
if configmap and configmap.data:
|
||||
executing_class = configmap.data.get(ACTIVE_TEST_CLASS)
|
||||
if executing_class and executing_class != cls.__name__:
|
||||
logger.info(f"Retrieved ConfigMap data: {configmap.data}")
|
||||
logger.info(f"[{cls.__name__}] exec completed, exiting waiter.")
|
||||
return
|
||||
if cls.process.poll() is None:
|
||||
# Process is still running
|
||||
time.sleep(30)
|
||||
@@ -1226,5 +1273,13 @@ class TestNpuPerfMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
"top_p": self.top_p,
|
||||
}
|
||||
logger.info(f"Starting benchmark with parameters: {bench_params}")
|
||||
metrics = run_bench_serving(**bench_params)
|
||||
if (
|
||||
self.dataset_name == "generated-shared-prefix"
|
||||
and self.pop_sglang_is_in_ci_for_gsp
|
||||
):
|
||||
bench_env = os.environ.copy()
|
||||
bench_env.pop("SGLANG_IS_IN_CI", None)
|
||||
else:
|
||||
bench_env = None
|
||||
metrics = run_bench_serving(**bench_params, env=bench_env)
|
||||
assert_metrics(self, metrics)
|
||||
|
||||
Reference in New Issue
Block a user