CI: use 'sglang serve' in CI tests (#18597)
Co-authored-by: Mick <mickjagger19@icloud.com> Co-authored-by: sglang-bot <sglangbot@gmail.com>
This commit is contained in:
co-authored by
Mick
sglang-bot
parent
776709efe8
commit
e6da514c2c
@@ -26,6 +26,33 @@ def _get_lock(model_name_or_path: str, cache_dir: Optional[str] = None):
|
|||||||
return lock
|
return lock
|
||||||
|
|
||||||
|
|
||||||
|
def _hf_hub_download(
|
||||||
|
repo_id: str,
|
||||||
|
filename: str,
|
||||||
|
local_dir: Optional[str] = None,
|
||||||
|
**kwargs,
|
||||||
|
) -> str:
|
||||||
|
"""Unified hf_hub_download supporting both Hugging Face Hub and ModelScope."""
|
||||||
|
if envs.SGLANG_USE_MODELSCOPE.get():
|
||||||
|
from modelscope import model_file_download
|
||||||
|
|
||||||
|
return model_file_download(
|
||||||
|
model_id=repo_id,
|
||||||
|
file_path=filename,
|
||||||
|
cache_dir=local_dir,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
from huggingface_hub import hf_hub_download as _hf_hub_download_impl
|
||||||
|
|
||||||
|
return _hf_hub_download_impl(
|
||||||
|
repo_id=repo_id,
|
||||||
|
filename=filename,
|
||||||
|
local_dir=local_dir,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Copied and adapted from hf_diffusers_utils.py
|
# Copied and adapted from hf_diffusers_utils.py
|
||||||
def _maybe_download_model(
|
def _maybe_download_model(
|
||||||
model_name_or_path: str, local_dir: str | None = None, download: bool = True
|
model_name_or_path: str, local_dir: str | None = None, download: bool = True
|
||||||
@@ -44,8 +71,6 @@ def _maybe_download_model(
|
|||||||
Local directory path that contains the downloaded config file, or the original local directory.
|
Local directory path that contains the downloaded config file, or the original local directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sglang.multimodal_gen.runtime.utils.hf_diffusers_utils import hf_hub_download
|
|
||||||
|
|
||||||
if os.path.exists(model_name_or_path):
|
if os.path.exists(model_name_or_path):
|
||||||
logger.debug("Model already exists locally")
|
logger.debug("Model already exists locally")
|
||||||
return model_name_or_path
|
return model_name_or_path
|
||||||
@@ -62,7 +87,7 @@ def _maybe_download_model(
|
|||||||
source_hub,
|
source_hub,
|
||||||
model_name_or_path,
|
model_name_or_path,
|
||||||
)
|
)
|
||||||
file_path = hf_hub_download(
|
file_path = _hf_hub_download(
|
||||||
repo_id=model_name_or_path,
|
repo_id=model_name_or_path,
|
||||||
filename="model_index.json",
|
filename="model_index.json",
|
||||||
local_dir=local_dir,
|
local_dir=local_dir,
|
||||||
@@ -79,7 +104,7 @@ def _maybe_download_model(
|
|||||||
source_hub,
|
source_hub,
|
||||||
model_name_or_path,
|
model_name_or_path,
|
||||||
)
|
)
|
||||||
file_path = hf_hub_download(
|
file_path = _hf_hub_download(
|
||||||
repo_id=model_name_or_path,
|
repo_id=model_name_or_path,
|
||||||
filename="config.json",
|
filename="config.json",
|
||||||
local_dir=local_dir,
|
local_dir=local_dir,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import inspect
|
|||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import socket
|
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
@@ -23,7 +22,6 @@ from typing import Any, TypeVar, cast
|
|||||||
import cloudpickle
|
import cloudpickle
|
||||||
import torch
|
import torch
|
||||||
import yaml
|
import yaml
|
||||||
from remote_pdb import RemotePdb
|
|
||||||
from torch.distributed.fsdp import MixedPrecisionPolicy
|
from torch.distributed.fsdp import MixedPrecisionPolicy
|
||||||
|
|
||||||
import sglang.multimodal_gen.envs as envs
|
import sglang.multimodal_gen.envs as envs
|
||||||
@@ -546,15 +544,6 @@ class TypeBasedDispatcher:
|
|||||||
raise ValueError(f"Invalid object: {obj}")
|
raise ValueError(f"Invalid object: {obj}")
|
||||||
|
|
||||||
|
|
||||||
# For non-torch.distributed debugging
|
|
||||||
def remote_breakpoint() -> None:
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
||||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
s.bind(("localhost", 0)) # Let the OS pick an ephemeral port.
|
|
||||||
port = s.getsockname()[1]
|
|
||||||
RemotePdb(host="localhost", port=port).set_trace()
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MixedPrecisionState:
|
class MixedPrecisionState:
|
||||||
param_dtype: torch.dtype | None = None
|
param_dtype: torch.dtype | None = None
|
||||||
|
|||||||
@@ -879,18 +879,22 @@ def popen_launch_server(
|
|||||||
|
|
||||||
use_mixed_pd_engine = not pd_separated and num_replicas is not None
|
use_mixed_pd_engine = not pd_separated and num_replicas is not None
|
||||||
if pd_separated or use_mixed_pd_engine:
|
if pd_separated or use_mixed_pd_engine:
|
||||||
command = "sglang.launch_pd_server"
|
command = [
|
||||||
|
"python3",
|
||||||
|
"-m",
|
||||||
|
"sglang.launch_pd_server",
|
||||||
|
"--model-path",
|
||||||
|
model,
|
||||||
|
*[str(x) for x in other_args],
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
command = "sglang.launch_server"
|
command = [
|
||||||
|
"sglang",
|
||||||
command = [
|
"serve",
|
||||||
"python3",
|
"--model-path",
|
||||||
"-m",
|
model,
|
||||||
command,
|
*[str(x) for x in other_args],
|
||||||
"--model-path",
|
]
|
||||||
model,
|
|
||||||
*[str(x) for x in other_args],
|
|
||||||
]
|
|
||||||
|
|
||||||
if pd_separated or use_mixed_pd_engine:
|
if pd_separated or use_mixed_pd_engine:
|
||||||
command.extend(["--lb-host", host, "--lb-port", port])
|
command.extend(["--lb-host", host, "--lb-port", port])
|
||||||
@@ -1308,7 +1312,7 @@ def run_score_benchmark(
|
|||||||
json=warmup_data,
|
json=warmup_data,
|
||||||
timeout=aiohttp.ClientTimeout(total=30),
|
timeout=aiohttp.ClientTimeout(total=30),
|
||||||
)
|
)
|
||||||
except:
|
except Exception:
|
||||||
pass # Ignore warmup errors
|
pass # Ignore warmup errors
|
||||||
|
|
||||||
test_requests = []
|
test_requests = []
|
||||||
@@ -1376,17 +1380,9 @@ def run_embeddings_benchmark(
|
|||||||
|
|
||||||
async def _run_benchmark():
|
async def _run_benchmark():
|
||||||
|
|
||||||
# Load tokenizer for generating test data
|
|
||||||
from sglang.srt.utils.hf_transformers_utils import get_tokenizer
|
|
||||||
|
|
||||||
tokenizer = get_tokenizer(model)
|
|
||||||
|
|
||||||
def generate_text_with_token_count(num_tokens):
|
def generate_text_with_token_count(num_tokens):
|
||||||
"""Generate text with precise token count using special tokens."""
|
"""Generate text with precise token count using special tokens."""
|
||||||
# Use a token that reliably produces 1 token
|
|
||||||
special_token = "<|im_start|>"
|
special_token = "<|im_start|>"
|
||||||
# Verify it's a single token
|
|
||||||
test_tokens = tokenizer.encode(special_token, add_special_tokens=False)
|
|
||||||
text = special_token * num_tokens
|
text = special_token * num_tokens
|
||||||
return text
|
return text
|
||||||
|
|
||||||
@@ -1406,7 +1402,7 @@ def run_embeddings_benchmark(
|
|||||||
json=warmup_data,
|
json=warmup_data,
|
||||||
timeout=aiohttp.ClientTimeout(total=30),
|
timeout=aiohttp.ClientTimeout(total=30),
|
||||||
)
|
)
|
||||||
except:
|
except Exception:
|
||||||
pass # Ignore warmup errors
|
pass # Ignore warmup errors
|
||||||
|
|
||||||
test_requests = []
|
test_requests = []
|
||||||
@@ -1822,7 +1818,7 @@ def run_mulit_request_test(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
ret = response.json()
|
response.json()
|
||||||
|
|
||||||
with ThreadPoolExecutor(2) as executor:
|
with ThreadPoolExecutor(2) as executor:
|
||||||
list(executor.map(run_one, list(range(4))))
|
list(executor.map(run_one, list(range(4))))
|
||||||
|
|||||||
Reference in New Issue
Block a user