import json import os import resource from json import JSONDecodeError from typing import Dict, List, Optional, Union import requests from tqdm.asyncio import tqdm from transformers import ( AutoProcessor, AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast, ) def remove_prefix(text: str, prefix: str) -> str: return text[len(prefix) :] if text.startswith(prefix) else text def remove_suffix(text: str, suffix: str) -> str: return text[: -len(suffix)] if text.endswith(suffix) else text def parse_custom_headers(header_list: List[str]) -> Dict[str, str]: return {k: v for h in header_list for k, _, v in [h.partition("=")] if k and v} def get_model(pretrained_model_name_or_path: str) -> str: if os.getenv("SGLANG_USE_MODELSCOPE", "false").lower() == "true": import huggingface_hub.constants from modelscope import snapshot_download model_path = snapshot_download( model_id=pretrained_model_name_or_path, local_files_only=huggingface_hub.constants.HF_HUB_OFFLINE, ignore_file_pattern=[".*.pt", ".*.safetensors", ".*.bin"], ) return model_path return pretrained_model_name_or_path def get_tokenizer( pretrained_model_name_or_path: str, ) -> Union[PreTrainedTokenizer, PreTrainedTokenizerFast]: assert ( pretrained_model_name_or_path is not None and pretrained_model_name_or_path != "" ) if pretrained_model_name_or_path.endswith( ".json" ) or pretrained_model_name_or_path.endswith(".model"): from sglang.srt.utils.hf_transformers_utils import get_tokenizer return get_tokenizer(pretrained_model_name_or_path) if pretrained_model_name_or_path is not None and not os.path.exists( pretrained_model_name_or_path ): pretrained_model_name_or_path = get_model(pretrained_model_name_or_path) return AutoTokenizer.from_pretrained( pretrained_model_name_or_path, trust_remote_code=True ) def get_processor( pretrained_model_name_or_path: str, ) -> AutoProcessor: assert ( pretrained_model_name_or_path is not None and pretrained_model_name_or_path != "" ) from sglang.srt.utils.hf_transformers_utils import ( get_processor as _srt_get_processor, ) if not pretrained_model_name_or_path.endswith( (".json", ".model") ) and not os.path.exists(pretrained_model_name_or_path): pretrained_model_name_or_path = get_model(pretrained_model_name_or_path) return _srt_get_processor(pretrained_model_name_or_path, trust_remote_code=True) def download_and_cache_hf_file( repo_id: str, filename: str, repo_type: str = "dataset", ): """Download a file from Hugging Face and cache it locally.""" from huggingface_hub import hf_hub_download return hf_hub_download(repo_id=repo_id, filename=filename, repo_type=repo_type) def download_and_cache_file(url: str, filename: Optional[str] = None): """Read and cache a file from a url.""" if filename is None: filename = os.path.join("/tmp", url.split("/")[-1]) # Check if the cache file already exists if is_file_valid_json(filename): return filename print(f"Downloading from {url} to {filename}") # Stream the response to show the progress bar response = requests.get(url, stream=True) response.raise_for_status() # Check for request errors # Total size of the file in bytes total_size = int(response.headers.get("content-length", 0)) chunk_size = 1024 # Download in chunks of 1KB # Use tqdm to display the progress bar with ( open(filename, "wb") as f, tqdm( desc=filename, total=total_size, unit="B", unit_scale=True, unit_divisor=1024, ) as bar, ): for chunk in response.iter_content(chunk_size=chunk_size): f.write(chunk) bar.update(len(chunk)) return filename def is_file_valid_json(path): if not os.path.isfile(path): return False # TODO can fuse into the real file open later try: with open(path) as f: json.load(f) return True except JSONDecodeError as e: print( f"{path} exists but json loading fails ({e=}), thus treat as invalid file" ) return False def set_ulimit(target_soft_limit=65535): resource_type = resource.RLIMIT_NOFILE current_soft, current_hard = resource.getrlimit(resource_type) if current_soft < target_soft_limit: try: resource.setrlimit(resource_type, (target_soft_limit, current_hard)) except ValueError as e: print(f"Fail to set RLIMIT_NOFILE: {e}")