e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
192 lines
5.6 KiB
Python
192 lines
5.6 KiB
Python
import warnings
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
|
|
|
|
class QuantType(Enum):
|
|
BNB = "bnb"
|
|
UNSLOTH = "unsloth" # dynamic 4-bit quantization
|
|
GGUF = "GGUF"
|
|
NONE = "none"
|
|
BF16 = "bf16" # only for Deepseek V3
|
|
|
|
|
|
# Tags for Hugging Face model paths
|
|
BNB_QUANTIZED_TAG = "bnb-4bit"
|
|
UNSLOTH_DYNAMIC_QUANT_TAG = "unsloth" + "-" + BNB_QUANTIZED_TAG
|
|
GGUF_TAG = "GGUF"
|
|
BF16_TAG = "bf16"
|
|
|
|
QUANT_TAG_MAP = {
|
|
QuantType.BNB: BNB_QUANTIZED_TAG,
|
|
QuantType.UNSLOTH: UNSLOTH_DYNAMIC_QUANT_TAG,
|
|
QuantType.GGUF: GGUF_TAG,
|
|
QuantType.NONE: None,
|
|
QuantType.BF16: BF16_TAG,
|
|
}
|
|
|
|
|
|
# NOTE: models registered with org="unsloth" and QUANT_TYPE.NONE are aliases of QUANT_TYPE.UNSLOTH
|
|
@dataclass
|
|
class ModelInfo:
|
|
org: str
|
|
base_name: str
|
|
version: str
|
|
size: int
|
|
name: str = None # constructed from base_name, version, size unless provided
|
|
is_multimodal: bool = False
|
|
instruct_tag: str = None
|
|
quant_type: QuantType = None
|
|
description: str = None
|
|
|
|
def __post_init__(self):
|
|
self.name = self.name or self.construct_model_name(
|
|
self.base_name,
|
|
self.version,
|
|
self.size,
|
|
self.quant_type,
|
|
self.instruct_tag,
|
|
)
|
|
|
|
@staticmethod
|
|
def append_instruct_tag(key: str, instruct_tag: str = None):
|
|
if instruct_tag:
|
|
key = "-".join([key, instruct_tag])
|
|
return key
|
|
|
|
@staticmethod
|
|
def append_quant_type(key: str, quant_type: QuantType = None):
|
|
if quant_type != QuantType.NONE:
|
|
key = "-".join([key, QUANT_TAG_MAP[quant_type]])
|
|
return key
|
|
|
|
@classmethod
|
|
def construct_model_name(
|
|
cls,
|
|
base_name,
|
|
version,
|
|
size,
|
|
quant_type,
|
|
instruct_tag,
|
|
key = "",
|
|
):
|
|
key = cls.append_instruct_tag(key, instruct_tag)
|
|
key = cls.append_quant_type(key, quant_type)
|
|
return key
|
|
|
|
@property
|
|
def model_path(self) -> str:
|
|
return f"{self.org}/{self.name}"
|
|
|
|
|
|
@dataclass
|
|
class ModelMeta:
|
|
org: str
|
|
base_name: str
|
|
model_version: str
|
|
model_info_cls: type[ModelInfo]
|
|
model_sizes: list[str] = field(default_factory = list)
|
|
instruct_tags: list[str] = field(default_factory = list)
|
|
quant_types: list[QuantType] | dict[str, list[QuantType]] = field(default_factory = list)
|
|
is_multimodal: bool = False
|
|
|
|
|
|
MODEL_REGISTRY: dict[str, ModelInfo] = {}
|
|
|
|
|
|
def register_model(
|
|
model_info_cls: ModelInfo,
|
|
org: str,
|
|
base_name: str,
|
|
version: str,
|
|
size: int,
|
|
instruct_tag: str = None,
|
|
quant_type: QuantType = None,
|
|
is_multimodal: bool = False,
|
|
name: str = None,
|
|
):
|
|
name = name or model_info_cls.construct_model_name(
|
|
base_name = base_name,
|
|
version = version,
|
|
size = size,
|
|
quant_type = quant_type,
|
|
instruct_tag = instruct_tag,
|
|
)
|
|
key = f"{org}/{name}"
|
|
|
|
if key in MODEL_REGISTRY:
|
|
raise ValueError(f"Model {key} already registered, current keys: {MODEL_REGISTRY.keys()}")
|
|
|
|
MODEL_REGISTRY[key] = model_info_cls(
|
|
org = org,
|
|
base_name = base_name,
|
|
version = version,
|
|
size = size,
|
|
is_multimodal = is_multimodal,
|
|
instruct_tag = instruct_tag,
|
|
quant_type = quant_type,
|
|
name = name,
|
|
)
|
|
|
|
|
|
def _check_model_info(model_id: str, properties: list[str] = ["lastModified"]):
|
|
from huggingface_hub import HfApi
|
|
from huggingface_hub import ModelInfo as HfModelInfo
|
|
from huggingface_hub.utils import RepositoryNotFoundError
|
|
|
|
api = HfApi()
|
|
|
|
try:
|
|
model_info: HfModelInfo = api.model_info(model_id, expand = properties)
|
|
except Exception as e:
|
|
if isinstance(e, RepositoryNotFoundError):
|
|
warnings.warn(f"{model_id} not found on Hugging Face")
|
|
model_info = None
|
|
else:
|
|
raise e
|
|
return model_info
|
|
|
|
|
|
def _register_models(model_meta: ModelMeta, include_original_model: bool = False):
|
|
org = model_meta.org
|
|
base_name = model_meta.base_name
|
|
instruct_tags = model_meta.instruct_tags
|
|
model_version = model_meta.model_version
|
|
model_sizes = model_meta.model_sizes
|
|
is_multimodal = model_meta.is_multimodal
|
|
quant_types = model_meta.quant_types
|
|
model_info_cls = model_meta.model_info_cls
|
|
|
|
for size in model_sizes:
|
|
for instruct_tag in instruct_tags:
|
|
# Handle quant types per model size
|
|
if isinstance(quant_types, dict):
|
|
_quant_types = quant_types[size]
|
|
else:
|
|
_quant_types = quant_types
|
|
for quant_type in _quant_types:
|
|
# NOTE: models registered with org="unsloth" and QUANT_TYPE.NONE are aliases of QUANT_TYPE.UNSLOTH
|
|
_org = "unsloth" # quantized versions of the original model
|
|
register_model(
|
|
model_info_cls = model_info_cls,
|
|
org = _org,
|
|
base_name = base_name,
|
|
version = model_version,
|
|
size = size,
|
|
instruct_tag = instruct_tag,
|
|
quant_type = quant_type,
|
|
is_multimodal = is_multimodal,
|
|
)
|
|
# include original model from releasing organization
|
|
if include_original_model:
|
|
register_model(
|
|
model_info_cls = model_info_cls,
|
|
org = org,
|
|
base_name = base_name,
|
|
version = model_version,
|
|
size = size,
|
|
instruct_tag = instruct_tag,
|
|
quant_type = QuantType.NONE,
|
|
is_multimodal = is_multimodal,
|
|
)
|