Skip to content
Open
21 changes: 17 additions & 4 deletions python/sglang/benchmark/datasets/longbench_v2.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import random
from argparse import Namespace
from dataclasses import dataclass
Expand All @@ -8,9 +9,24 @@
from sglang.benchmark.datasets.common import BaseDataset, DatasetRow

LONGBENCH_V2_REPO_ID = "THUDM/LongBench-v2"
# Pinned to a commit so a cached copy loads without any Hub API call.
LONGBENCH_V2_REVISION = "2b48e494f2c7a2f0af81aae178e05c7e1dde0fe9"
LONGBENCH_V2_DEFAULT_OUTPUT_LEN = 10 # answer letter + short explanation


def load_longbench_v2_examples() -> List[dict]:
from huggingface_hub import hf_hub_download

path = hf_hub_download(
LONGBENCH_V2_REPO_ID,
"data.json",
repo_type="dataset",
revision=LONGBENCH_V2_REVISION,
)
with open(path) as f:
return json.load(f)


def _format_prompt(example: dict) -> str:
return (
f"{example['context']}\n\n"
Expand Down Expand Up @@ -78,10 +94,7 @@ def sample_longbench_v2_requests(
with open(dataset_path) as f:
examples = [json.loads(line) for line in f if line.strip()]
else:
from datasets import load_dataset

ds = load_dataset(LONGBENCH_V2_REPO_ID, split="train")
examples = list(ds)
examples = load_longbench_v2_examples()

random.shuffle(examples)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from sglang.multimodal_gen.runtime.server_args import ServerArgs
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.multimodal_gen.runtime.utils.precision_types import PRECISION_TO_TYPE
from sglang.srt.utils.common import retry_on_hub_rate_limit

logger = init_logger(__name__)

Expand Down Expand Up @@ -158,9 +159,11 @@ def _resolve_shape_dir(
"Local path %s not found, downloading from HuggingFace Hub",
local_path,
)
downloaded = snapshot_download(
repo_id=model_path,
allow_patterns=[f"{subfolder}/**"],
downloaded = retry_on_hub_rate_limit(
lambda: snapshot_download(
repo_id=model_path,
allow_patterns=[f"{subfolder}/**"],
)
)
local_path = os.path.join(downloaded, subfolder)

Expand Down Expand Up @@ -205,9 +208,11 @@ def _resolve_model_subfolder(
"Local path %s not found, downloading from HuggingFace Hub",
local_path,
)
downloaded = snapshot_download(
repo_id=model_path,
allow_patterns=[f"{subfolder}/**"],
downloaded = retry_on_hub_rate_limit(
lambda: snapshot_download(
repo_id=model_path,
allow_patterns=[f"{subfolder}/**"],
)
)
local_path = os.path.join(downloaded, subfolder)

Expand Down
27 changes: 16 additions & 11 deletions python/sglang/multimodal_gen/runtime/pipelines/ideogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
verify_model_config_and_directory,
)
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.srt.utils.common import retry_on_hub_rate_limit

logger = init_logger(__name__)

Expand Down Expand Up @@ -70,12 +71,14 @@ def _resolve_ideogram4_distilled_components_path() -> str:
# fal's model cards explicitly reference the NF4 Diffusers repository for
# these shared components. Download only those components: its conditional
# and unconditional base transformers are unused by distilled variants.
return snapshot_download(
repo_id=_IDEOGRAM4_DISTILLED_COMPONENTS_MODEL,
revision=_IDEOGRAM4_DISTILLED_COMPONENTS_REVISION,
allow_patterns=_IDEOGRAM4_DISTILLED_COMPONENT_PATTERNS,
ignore_patterns=["*.onnx", "*.msgpack"],
max_workers=8,
return retry_on_hub_rate_limit(
lambda: snapshot_download(
repo_id=_IDEOGRAM4_DISTILLED_COMPONENTS_MODEL,
revision=_IDEOGRAM4_DISTILLED_COMPONENTS_REVISION,
allow_patterns=_IDEOGRAM4_DISTILLED_COMPONENT_PATTERNS,
ignore_patterns=["*.onnx", "*.msgpack"],
max_workers=8,
)
)


Expand Down Expand Up @@ -289,11 +292,13 @@ def _resolve_distilled_transformer_path(self) -> str:
model_path = (
self.model_path
if os.path.exists(self.model_path)
else snapshot_download(
repo_id=self.model_path,
allow_patterns=["transformer/*"],
ignore_patterns=["*.onnx", "*.msgpack"],
max_workers=8,
else retry_on_hub_rate_limit(
lambda: snapshot_download(
repo_id=self.model_path,
allow_patterns=["transformer/*"],
ignore_patterns=["*.onnx", "*.msgpack"],
max_workers=8,
)
)
)
self._distilled_transformer_path = os.path.join(model_path, "transformer")
Expand Down
13 changes: 8 additions & 5 deletions python/sglang/multimodal_gen/runtime/utils/model_overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from sglang.multimodal_gen import envs
from sglang.multimodal_gen.runtime.loader.weight_utils import get_lock
from sglang.multimodal_gen.runtime.utils.logging_utils import init_logger
from sglang.srt.utils.common import retry_on_hub_rate_limit
from sglang.utils import load_diffusion_overlay_registry_from_env

logger = init_logger(__name__)
Expand Down Expand Up @@ -470,11 +471,13 @@ def download_overlay_metadata(
overlay_repo_id,
)
return str(
snapshot_download_fn(
repo_id=overlay_repo_id,
allow_patterns=MODEL_OVERLAY_METADATA_PATTERNS,
revision=revision,
max_workers=4,
retry_on_hub_rate_limit(
lambda: snapshot_download_fn(
repo_id=overlay_repo_id,
allow_patterns=MODEL_OVERLAY_METADATA_PATTERNS,
revision=revision,
max_workers=4,
)
)
)

Expand Down
7 changes: 4 additions & 3 deletions python/sglang/multimodal_gen/runtime/weights/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from huggingface_hub import HfApi, hf_hub_download
from huggingface_hub.utils import validate_repo_id

from sglang.srt.utils.common import retry_on_hub_rate_limit

WeightSourceKind = Literal["local", "huggingface"]

_WEIGHT_SUFFIXES = (".safetensors", ".gguf", ".bin", ".pt", ".pth", ".ckpt")
Expand Down Expand Up @@ -274,9 +276,8 @@ def resolve_weight_inventory(source: WeightSource) -> WeightInventory:
)

assert source.repo_id is not None
model_info = HfApi().model_info(
source.repo_id,
revision=source.revision,
model_info = retry_on_hub_rate_limit(
lambda: HfApi().model_info(source.repo_id, revision=source.revision)
)
files = tuple(sibling.rfilename for sibling in model_info.siblings)
return WeightInventory(
Expand Down
19 changes: 17 additions & 2 deletions python/sglang/srt/arg_groups/model_path_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
resolving_view,
run_post_process_pass,
)
from sglang.srt.utils.common import is_remote_url
from sglang.srt.utils.common import find_local_repo_dir, is_remote_url
from sglang.srt.utils.hf_transformers_utils import check_gguf_file
from sglang.srt.utils.runai_utils import ObjectStorageModel, is_runai_obj_uri

Expand Down Expand Up @@ -347,10 +347,25 @@ def _check_format(has_params, has_consolidated, has_hf_weights) -> bool:
),
)

snapshot_dir = find_local_repo_dir(cfg.model_path, revision=cfg.revision)
if snapshot_dir is not None:
# A cache may hold only some files, so trust it only when what it has decides.
has_params = os.path.exists(os.path.join(snapshot_dir, "params.json"))
has_hf_weights = bool(
glob.glob(os.path.join(snapshot_dir, "model*.safetensors"))
)
if has_params and name_matches:
return True
if has_hf_weights and not name_matches:
return False

try:
from huggingface_hub import HfApi

files = {s.rfilename for s in HfApi().model_info(cfg.model_path).siblings}
files = {
s.rfilename
for s in HfApi().model_info(cfg.model_path, revision=cfg.revision).siblings
}
return _check_format(
has_params="params.json" in files,
has_consolidated=any(
Expand Down
24 changes: 12 additions & 12 deletions python/sglang/srt/lora/lora_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import os
from typing import Dict, Optional

from huggingface_hub import snapshot_download
from huggingface_hub import hf_hub_download

from sglang.srt.utils.common import download_hf_file_if_exists

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -76,27 +78,25 @@ def get_lora_config(self, dummy=False):
if dummy:
raise NotImplementedError()
else:
config_name = "adapter_config.json"
if not os.path.isdir(self.path):
weights_dir = snapshot_download(self.path, allow_patterns=["*.json"])
config_path = hf_hub_download(repo_id=self.path, filename=config_name)
else:
weights_dir = self.path
config_name = "adapter_config.json"
with open(os.path.join(weights_dir, config_name), "r") as f:
config_path = os.path.join(self.path, config_name)
with open(config_path, "r") as f:
return json.load(f)

def get_added_tokens_config(self):
"""Load added tokens from the LoRA adapter if the file exists."""
# Determine the weights directory
if not os.path.isdir(self.path):
weights_dir = snapshot_download(self.path, allow_patterns=["*.json"])
added_tokens_path = download_hf_file_if_exists(
repo_id=self.path, filename="added_tokens.json"
)
else:
weights_dir = self.path

# Construct the path to added_tokens.json
added_tokens_path = os.path.join(weights_dir, "added_tokens.json")
added_tokens_path = os.path.join(self.path, "added_tokens.json")

# Return None if the file doesn't exist (optional for standard LoRA adapters)
if not os.path.exists(added_tokens_path):
if added_tokens_path is None or not os.path.exists(added_tokens_path):
return None

# Load and return the added tokens
Expand Down
51 changes: 33 additions & 18 deletions python/sglang/srt/model_loader/ci_weight_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@

import safetensors

from sglang.srt.utils import log_info_on_rank0
from sglang.srt.utils import (
find_local_repo_dir,
log_info_on_rank0,
retry_on_hub_rate_limit,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -152,11 +156,20 @@ def validate_cache_lightweight(
custom_files = set()
for key, value in auto_map.items():
if isinstance(value, str) and "." in value:
module_name = value.split(".")[0]
custom_files.add(f"{module_name}.py")
# "owner/repo--module.Class" loads its code from another repo.
code_repo, _, reference = value.rpartition("--")
code_dir = (
find_local_repo_dir(code_repo)
if code_repo
else snapshot_dir
)
if code_dir is None:
return False
module_name = reference.split(".")[0]
custom_files.add(os.path.join(code_dir, f"{module_name}.py"))

for custom_file in custom_files:
custom_file_path = os.path.join(snapshot_dir, custom_file)
for custom_file_path in custom_files:
custom_file = os.path.basename(custom_file_path)
if not os.path.exists(custom_file_path):
logger.debug(
"Custom module file not in snapshot: %s for %s",
Expand Down Expand Up @@ -782,19 +795,21 @@ def __init__(self, *args, **kwargs):
hf_folder = None
for attempt in range(max_retries):
try:
hf_folder = snapshot_download(
model_name_or_path,
allow_patterns=allow_patterns,
ignore_patterns=ignore_patterns,
cache_dir=cache_dir,
tqdm_class=DisabledTqdm,
revision=revision,
local_files_only=huggingface_hub.constants.HF_HUB_OFFLINE,
# Force single-threaded downloads to prevent race conditions
# on NFS. HF hub defaults to max_workers=8, which can cause
# .incomplete file conflicts when multiple threads operate
# on the same files
max_workers=1,
hf_folder = retry_on_hub_rate_limit(
lambda: snapshot_download(
model_name_or_path,
allow_patterns=allow_patterns,
ignore_patterns=ignore_patterns,
cache_dir=cache_dir,
tqdm_class=DisabledTqdm,
revision=revision,
local_files_only=huggingface_hub.constants.HF_HUB_OFFLINE,
# Force single-threaded downloads to prevent race conditions
# on NFS. HF hub defaults to max_workers=8, which can cause
# .incomplete file conflicts when multiple threads operate
# on the same files
max_workers=1,
)
)
except (FileNotFoundError, OSError) as e:
# Race condition: .incomplete file was moved/deleted by another
Expand Down
Loading
Loading