zodiac.providers.pools
Feed models to RegistryEntry class
1# # # <!-- // /* SPDX-License-Identifier: MPL-2.0 */ --> 2# # # <!-- // /* d a r k s h a p e s */ --> 3 4"""Feed models to RegistryEntry class""" 5 6# pylint:disable=protected-access, no-member 7from typing import Any, Callable, Dict, List, Optional 8 9from nnll.model_detect.identity import ModelIdentity 10from nnll.mir.json_cache import MODES_PATH_NAMED, JSONCache 11from zodiac.providers.constants import CUETYPE_CONFIG, MIR_DB, CueType, PkgType, VALID_TASKS 12from zodiac.providers.registry_entry import RegistryEntry 13from nnll.monitor.file import dbuq 14 15nfo = print 16 17MODE_DATA = JSONCache(MODES_PATH_NAMED) 18 19 20@MODE_DATA.decorator 21async def add_mode_types(mir_tag: list[str], data: dict | None = None) -> dict[str, list[str] | str]: 22 """Add mode‑related metadata for a given MIR tag.\n 23 :param mir_tag: List of tag components that identify a model in the MIR database. 24 :param data: Dictionary containing mode entries; defaults to ``None``. 25 :returns: Mapping with keys extracted from ``data`` for the fused tag.""" 26 27 fused_tag = mir_tag 28 mir_details = { 29 "mode": data.get(fused_tag, {}).get("pipeline"), 30 "pkg_type": data.get(fused_tag, {}).get("library"), 31 "tags": data.get(fused_tag, {}).get("tags"), 32 } 33 return mir_details 34 35 36async def add_pkg_types(pkg_data: dict, mode: str, mir_tag: list[str]) -> dict[int | str, Any]: 37 """Augment package data with additional entries based on pipeline class and mode.\n 38 :param pkg_data: Existing package mapping where keys are indices and values are package specs. 39 :param mode: The pipeline mode extracted from MIR metadata. 40 :returns: Updated ``pkg_data`` with GPU-specific packages""" 41 package_name = pkg_data.get(next(iter(pkg_data))) 42 class_name = package_name.get(next(iter(package_name))) 43 class_name = list(class_name)[0] 44 # if (class_name == "FluxPipeline" or "flux1" in mir_tag[0]) and PkgType.MFLUX.value[0]: 45 # alias = "schnell" if "schnell" in mir_tag[0] else "dev" 46 # class_data = { 47 # f"{PkgType.MFLUX.value[1].lower()}": "flux.flux.Flux1", 48 # } 49 # pkg_data.setdefault(str(len(pkg_data)), class_data) 50 if class_name == "ChromaPipeline" and PkgType.MLX_CHROMA.value[0]: 51 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_CHROMA.value[1].lower(): "ChromaPipeline"}) 52 if mode in VALID_TASKS[CueType.HUB][("text", "text")] and PkgType.MLX_LM.value[0]: 53 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_LM.value[1].lower(): "load"}) 54 if mode in VALID_TASKS[CueType.HUB][("image", "text")] and PkgType.MLX_VLM.value[0]: 55 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_LM.value[1].lower(): "load"}) 56 return pkg_data 57 58 59async def generate_entry(mir_tag: List[str], mir_db: dict, model_tags: list[str] | None = None, pkg_data: dict | None = None) -> dict[str, list[str] | str]: 60 """Create a registry entry dictionary from MIR information.\n 61 :param mir_tag: The hierarchical tag identifying a model in the MIR database. 62 :param mir_db: The MIR database instance providing access to stored metadata. 63 :param model_tags: Additional tags to attach to the model; defaults to ``None``. 64 :param pkg_data: Existing package data; defaults to ``None``. 65 :returns: Mapping of values for registry construction.""" 66 from zodiac.streams.class_stream import ancestor_data 67 68 fused_tag = ".".join(mir_tag) 69 mir_info = mir_db.database.get(mir_tag[0], {}).get(mir_tag[1]) 70 modalities = await add_mode_types(fused_tag) 71 mode_data = modalities.get("mode") 72 if tags := modalities.get("tags", []): 73 model_tags = tags if not model_tags else model_tags + tags 74 if not mir_info: 75 mir_info = {} 76 else: 77 pkg_data = mir_info.get("pkg") 78 if pkg_data: 79 pkg_data: dict = await add_pkg_types(pkg_data, mode_data, mir_tag) 80 pipe_data = mir_info.get("pipe_names") 81 if not pipe_data: 82 pipe_data: list[dict] = await ancestor_data(mir_tag, field_name="pipe_names") 83 pipe_data: dict | None = next(iter(pipe_data), {}) 84 task_data = mir_info.get("tasks") 85 if not task_data: 86 task_data: list[dict] = await ancestor_data(mir_tag, field_name="tasks") 87 entry_data = { 88 "mir": mir_tag, 89 "tasks": task_data, 90 "modules": pkg_data, 91 "pipe": pipe_data, 92 "mode": mode_data, 93 "tags": model_tags, 94 } 95 return entry_data 96 97 98async def hub_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 99 """Build a registry of models from the local Huggingface Hub cache\n 100 :param mir_db: An existing instance of the MIR database 101 :param api_data: Dictionary of service data pertaining to providers 102 :param entries: Previous registry entries to append 103 :return: A list of RegistryEntry elements, or None""" 104 105 from huggingface_hub import CacheNotFound, repocard, scan_cache_dir 106 from huggingface_hub.errors import EntryNotFoundError, LocalEntryNotFoundError, OfflineModeIsEnabled 107 from requests import HTTPError 108 109 entry_data = {} 110 111 async def generate_cache_data() -> Any: 112 try: 113 cache_dir = scan_cache_dir() 114 except CacheNotFound: 115 nfo("Cache error: No HuggingFace cache found") 116 yield None, None 117 else: 118 for repo in cache_dir.repos: 119 try: 120 card = repocard.RepoCard.load(repo.repo_id) 121 except (LocalEntryNotFoundError, EntryNotFoundError, HTTPError, OfflineModeIsEnabled) as error_log: 122 nfo(f"Pooling error: '{error_log}'") 123 yield None, None 124 yield repo, card 125 126 async for repo, card in generate_cache_data(): 127 model_id = ModelIdentity() 128 if repo: 129 tags = [] 130 base_model = None 131 tokenizer = None 132 pkg_type = None 133 mir_tags = None 134 card_data = getattr(card, "data", None) 135 if card_data: 136 base_model = card_data.get("base_model") 137 if isinstance(base_model, str): 138 base_model = [base_model] 139 pipeline_tag = card_data.get("pipeline_tag") 140 if tags: 141 tags.append(pipeline_tag) 142 else: 143 tags = [pipeline_tag] 144 if pkg_name := card_data.get("library_name"): 145 if hasattr(PkgType, pkg_name := pkg_name.replace("-", "_").upper()): 146 pkg_type = getattr(PkgType, pkg_name) 147 tokenizer = await model_id.get_cache_path(file_name="tokenizer.json", repo_obj=repo) 148 mir_tags = await model_id.label_model( 149 repo_id=repo.repo_id, 150 base_model=base_model if isinstance(base_model, str) or base_model is None else base_model[0], 151 cue_type=CueType.HUB.value[1], 152 ) 153 tags = card_data.get("tags", []) if card_data else None 154 if mir_tags: 155 if isinstance(mir_tags, list) and isinstance(mir_tags[0], list): 156 mir_bundle = mir_tags if len(mir_tags) > 1 else None 157 dbuq(mir_tags) 158 mir_tag = next(iter(mir_id for mir_id in mir_tags if any(arch for arch in [".dit.", "unet"] if arch in mir_id[0])), mir_tags[0]) 159 else: 160 mir_bundle = None 161 mir_tag = mir_tags 162 base_model = base_model.append(mir_tag[0]) if base_model else [mir_tag[0]] 163 entry_data = await generate_entry(mir_tag=mir_tag, mir_db=mir_db, model_tags=tags) 164 entry_data.setdefault("bundle", mir_bundle) 165 else: 166 mir_tags = [[]] 167 entry_data = { 168 "tags": [], 169 } 170 nfo(mir_tags if mir_tags[0] else f"mir tag not found for {repo.repo_id}") 171 entry = RegistryEntry.create_entry( 172 model=repo.repo_id, 173 size=repo.size_on_disk, 174 cuetype=CueType.HUB, 175 package=pkg_type, 176 model_family=base_model if base_model else [""], 177 path=str(repo.repo_path), 178 api_kwargs=api_data[CueType.HUB.value[1]], # api_data based on package_name (diffusers/mlx_audio) 179 timestamp=int(repo.last_modified), 180 tokenizer=tokenizer, 181 **entry_data, 182 ) 183 entries.append(entry) 184 return entries 185 186 187async def ollama_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 188 """Build a registry of models from local Ollama service\n 189 :param mir_db: An existing instance of the MIR database 190 :param api_data: Dictionary of service data pertaining to providers 191 :param entries: Previous registry entries to append 192 :return: A list of RegistryEntry elements, or None""" 193 194 async def generate_cache_data() -> Any: 195 from ollama import ListResponse, show, list as ollama_list 196 197 cache_dir: ListResponse = ollama_list() 198 if cache_dir: 199 for model in cache_dir.models: 200 gguf_data = show(model.model) 201 yield model, gguf_data 202 203 entry_data = {} 204 entries = [] if not entries else entries 205 config = api_data[CueType.OLLAMA.value[1]] 206 async for model, gguf_data in generate_cache_data(): 207 model_id = ModelIdentity() 208 base_model = gguf_data.modelinfo.get("general.architecture") 209 gguf_data = (gguf_data.modelfile,) 210 if hasattr(model, "family") and model.details.family != base_model: 211 base_model = model.details.family 212 if mir_tag := await model_id.label_model(repo_id=model.model, base_model=base_model, cue_type=CueType.OLLAMA.value[1], repo_obj=gguf_data): 213 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, model_tags=[model.details.family]) 214 nfo(f"no tag for {model.model}") if not mir_tag else nfo(f"{mir_tag}") 215 entry = RegistryEntry.create_entry( 216 model=f"{api_data[CueType.OLLAMA.value[1]].get('prefix')}{model.model}", 217 size=model.size.real, 218 model_family=[base_model], 219 cuetype=CueType.OLLAMA, 220 package=PkgType.LLAMA, 221 api_kwargs=config["api_kwargs"], 222 timestamp=int(model.modified_at.timestamp()), 223 tokenizer=None, 224 **entry_data, 225 ) 226 entries.append(entry) 227 return entries 228 229 230async def vllm_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 231 """Build a registry of models from local VLLM service\n 232 :param mir_db: An existing instance of the MIR database 233 :param api_data: Dictionary of service data pertaining to providers 234 :param entries: Previous registry entries to append 235 :return: A list of RegistryEntry elements, or None""" 236 237 from openai import OpenAI 238 239 entry_data = {} 240 entries = [] if not entries else entries 241 config = api_data[CueType.VLLM.value[1]] 242 cache_dir = OpenAI(base_url=api_data["VLLM"]["api_kwargs"]["api_base"], api_key=api_data["VLLM"]["api_kwargs"]["api_key"]) 243 for model in cache_dir.models.list().data: 244 model_id = ModelIdentity() 245 id_name = model["data"].get("id") 246 mir_tag = None 247 if id_name: 248 if mir_tag := await model_id.label_model(repo_id=id_name, base_model=None, cue_type=CueType.VLLM.value[1]): 249 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=["text"]) 250 entry = RegistryEntry.create_entry( 251 model=f"{api_data[CueType.VLLM.value[1]].get('prefix')}{id_name}", 252 size=model._data.size_bytes, 253 cuetype=CueType.VLLM, 254 api_kwargs={**config["api_kwargs"]}, 255 timestamp=int(model.modified_at.timestamp()), 256 **entry_data, 257 ) 258 entries.append(entry) 259 return entries 260 261 262async def llamafile_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 263 """Build a registry of models from a local Llamafile server\n 264 :param mir_db: An existing instance of the MIR database 265 :param api_data: Dictionary of service data pertaining to providers 266 :param entries: Previous registry entries to append 267 :return: A list of RegistryEntry elements, or None""" 268 from openai import OpenAI 269 270 entry_data = {} 271 mir_tag = None 272 entries = [] if not entries else entries 273 cache_dir: OpenAI = OpenAI(base_url=api_data["LLAMAFILE"]["api_kwargs"]["api_base"], api_key="sk-no-key-required") 274 config = api_data[CueType.LLAMAFILE.value[1]] 275 for model in cache_dir.models.list().data: 276 model_id = ModelIdentity() 277 if hasattr(model, id): 278 if mir_tag := await model_id.label_model(model.id, CueType.LLAMAFILE.value[1]): 279 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=["text"]) 280 entry = RegistryEntry.create_entry( 281 model=f"{api_data[CueType.LLAMAFILE.value[1]].get('prefix')}{model.id}", 282 size=0, 283 cuetype=CueType.LLAMAFILE, 284 api_kwargs=config["api_kwargs"], 285 timestamp=int(model.created), 286 **entry_data, 287 ) 288 entries.append(entry) 289 return entries 290 291 292async def lm_studio_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 293 """Build a registry of models from local LM Studio service\n 294 :param mir_db: An existing instance of the MIR database 295 :param api_data: Dictionary of service data pertaining to providers 296 :param entries: Previous registry entries to append 297 :return: A list of RegistryEntry elements, or None""" 298 299 from lmstudio import LMStudioClient 300 301 entry_data = {} 302 entries = [] if not entries else entries 303 client = LMStudioClient() 304 models = client.list_models() 305 config = api_data[CueType.LM_STUDIO.value[1]] 306 for model in models: 307 model_id = ModelIdentity() 308 tags = [] 309 if hasattr(model, "vision"): 310 tags.extend(["vision", model.vision]) 311 if hasattr(model, "tool_use"): 312 tags.append(["tool", model.tool_use]) 313 mir_tag = None 314 if hasattr(model, "architecture"): 315 if mir_tag := await model_id.label_model(model.architecture, None, CueType.LM_STUDIO.value[1]): 316 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=tags) 317 entry = RegistryEntry.create_entry( 318 model=f"{api_data[CueType.LM_STUDIO.value[1]].get('prefix')}{model.model_key}", 319 size=model._data.size_bytes, 320 cuetype=CueType.LM_STUDIO, 321 api_kwargs={**config["api_kwargs"]}, 322 timestamp=int(model.modified_at.timestamp()), 323 **entry_data, 324 ) 325 entries.append(entry) 326 return entries 327 328 329async def register_models(data: Optional[Dict[str, Any]] = None) -> list[RegistryEntry] | None: 330 """Retrieve models from ollama server, local huggingface hub cache, local lmstudio cache & vllm.\n 331 :param: data: Testing - Override for API CueType data dictionary 332 我們不應該繼續為LMStudio編碼。 歡迎貢獻者來改進它。 LMStudio is not OSS, but contributions are welcome.""" 333 334 @CUETYPE_CONFIG.decorator 335 async def read_cuetype(data: Optional[Dict[str, Any]] = None) -> dict: 336 return data 337 338 if not data: 339 data = await read_cuetype() 340 341 async def entry_generator(): 342 entry_map = { 343 CueType.HUB.value: hub_pool, 344 CueType.OLLAMA.value: ollama_pool, 345 CueType.LLAMAFILE.value: llamafile_pool, 346 CueType.VLLM.value: vllm_pool, 347 CueType.LM_STUDIO.value: lm_studio_pool, 348 } 349 for cue_type, pool in entry_map.items(): 350 yield cue_type, pool 351 352 entries = [] 353 async for cue_type, provider in entry_generator(): 354 if cue_type[0]: 355 api_data = data 356 entries = await provider(api_data=api_data, mir_db=MIR_DB, entries=entries) 357 358 return sorted(entries, key=lambda x: x.timestamp, reverse=True) 359 360 361def generate_pool(): 362 import asyncio 363 from time import perf_counter 364 from nnll.monitor.console import nfo 365 366 start = perf_counter() 367 models = asyncio.run(register_models()) 368 nfo(f'Complete. Time: {perf_counter() - start}" Registered: {len(models)}') 369 return models 370 371 372if __name__ == "__main__": 373 import asyncio 374 from nnll.monitor.file import dbuq 375 376 models = asyncio.run(register_models()) 377 dbuq(models) 378 from pprint import pprint 379 380 pprint(models)
Prints the values to a stream, or to sys.stdout by default.
sep string inserted between values, default a space. end string appended after the last value, default a newline. file a file-like object (stream); defaults to the current sys.stdout. flush whether to forcibly flush the stream.
21@MODE_DATA.decorator 22async def add_mode_types(mir_tag: list[str], data: dict | None = None) -> dict[str, list[str] | str]: 23 """Add mode‑related metadata for a given MIR tag.\n 24 :param mir_tag: List of tag components that identify a model in the MIR database. 25 :param data: Dictionary containing mode entries; defaults to ``None``. 26 :returns: Mapping with keys extracted from ``data`` for the fused tag.""" 27 28 fused_tag = mir_tag 29 mir_details = { 30 "mode": data.get(fused_tag, {}).get("pipeline"), 31 "pkg_type": data.get(fused_tag, {}).get("library"), 32 "tags": data.get(fused_tag, {}).get("tags"), 33 } 34 return mir_details
Add mode‑related metadata for a given MIR tag.
Parameters
- mir_tag: List of tag components that identify a model in the MIR database.
- data: Dictionary containing mode entries; defaults to
None. :returns: Mapping with keys extracted fromdatafor the fused tag.
37async def add_pkg_types(pkg_data: dict, mode: str, mir_tag: list[str]) -> dict[int | str, Any]: 38 """Augment package data with additional entries based on pipeline class and mode.\n 39 :param pkg_data: Existing package mapping where keys are indices and values are package specs. 40 :param mode: The pipeline mode extracted from MIR metadata. 41 :returns: Updated ``pkg_data`` with GPU-specific packages""" 42 package_name = pkg_data.get(next(iter(pkg_data))) 43 class_name = package_name.get(next(iter(package_name))) 44 class_name = list(class_name)[0] 45 # if (class_name == "FluxPipeline" or "flux1" in mir_tag[0]) and PkgType.MFLUX.value[0]: 46 # alias = "schnell" if "schnell" in mir_tag[0] else "dev" 47 # class_data = { 48 # f"{PkgType.MFLUX.value[1].lower()}": "flux.flux.Flux1", 49 # } 50 # pkg_data.setdefault(str(len(pkg_data)), class_data) 51 if class_name == "ChromaPipeline" and PkgType.MLX_CHROMA.value[0]: 52 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_CHROMA.value[1].lower(): "ChromaPipeline"}) 53 if mode in VALID_TASKS[CueType.HUB][("text", "text")] and PkgType.MLX_LM.value[0]: 54 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_LM.value[1].lower(): "load"}) 55 if mode in VALID_TASKS[CueType.HUB][("image", "text")] and PkgType.MLX_VLM.value[0]: 56 pkg_data.setdefault(str(len(pkg_data)), {PkgType.MLX_LM.value[1].lower(): "load"}) 57 return pkg_data
Augment package data with additional entries based on pipeline class and mode.
Parameters
- pkg_data: Existing package mapping where keys are indices and values are package specs.
- mode: The pipeline mode extracted from MIR metadata.
:returns: Updated
pkg_datawith GPU-specific packages
60async def generate_entry(mir_tag: List[str], mir_db: dict, model_tags: list[str] | None = None, pkg_data: dict | None = None) -> dict[str, list[str] | str]: 61 """Create a registry entry dictionary from MIR information.\n 62 :param mir_tag: The hierarchical tag identifying a model in the MIR database. 63 :param mir_db: The MIR database instance providing access to stored metadata. 64 :param model_tags: Additional tags to attach to the model; defaults to ``None``. 65 :param pkg_data: Existing package data; defaults to ``None``. 66 :returns: Mapping of values for registry construction.""" 67 from zodiac.streams.class_stream import ancestor_data 68 69 fused_tag = ".".join(mir_tag) 70 mir_info = mir_db.database.get(mir_tag[0], {}).get(mir_tag[1]) 71 modalities = await add_mode_types(fused_tag) 72 mode_data = modalities.get("mode") 73 if tags := modalities.get("tags", []): 74 model_tags = tags if not model_tags else model_tags + tags 75 if not mir_info: 76 mir_info = {} 77 else: 78 pkg_data = mir_info.get("pkg") 79 if pkg_data: 80 pkg_data: dict = await add_pkg_types(pkg_data, mode_data, mir_tag) 81 pipe_data = mir_info.get("pipe_names") 82 if not pipe_data: 83 pipe_data: list[dict] = await ancestor_data(mir_tag, field_name="pipe_names") 84 pipe_data: dict | None = next(iter(pipe_data), {}) 85 task_data = mir_info.get("tasks") 86 if not task_data: 87 task_data: list[dict] = await ancestor_data(mir_tag, field_name="tasks") 88 entry_data = { 89 "mir": mir_tag, 90 "tasks": task_data, 91 "modules": pkg_data, 92 "pipe": pipe_data, 93 "mode": mode_data, 94 "tags": model_tags, 95 } 96 return entry_data
Create a registry entry dictionary from MIR information.
Parameters
- mir_tag: The hierarchical tag identifying a model in the MIR database.
- mir_db: The MIR database instance providing access to stored metadata.
- model_tags: Additional tags to attach to the model; defaults to
None. - pkg_data: Existing package data; defaults to
None. :returns: Mapping of values for registry construction.
99async def hub_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 100 """Build a registry of models from the local Huggingface Hub cache\n 101 :param mir_db: An existing instance of the MIR database 102 :param api_data: Dictionary of service data pertaining to providers 103 :param entries: Previous registry entries to append 104 :return: A list of RegistryEntry elements, or None""" 105 106 from huggingface_hub import CacheNotFound, repocard, scan_cache_dir 107 from huggingface_hub.errors import EntryNotFoundError, LocalEntryNotFoundError, OfflineModeIsEnabled 108 from requests import HTTPError 109 110 entry_data = {} 111 112 async def generate_cache_data() -> Any: 113 try: 114 cache_dir = scan_cache_dir() 115 except CacheNotFound: 116 nfo("Cache error: No HuggingFace cache found") 117 yield None, None 118 else: 119 for repo in cache_dir.repos: 120 try: 121 card = repocard.RepoCard.load(repo.repo_id) 122 except (LocalEntryNotFoundError, EntryNotFoundError, HTTPError, OfflineModeIsEnabled) as error_log: 123 nfo(f"Pooling error: '{error_log}'") 124 yield None, None 125 yield repo, card 126 127 async for repo, card in generate_cache_data(): 128 model_id = ModelIdentity() 129 if repo: 130 tags = [] 131 base_model = None 132 tokenizer = None 133 pkg_type = None 134 mir_tags = None 135 card_data = getattr(card, "data", None) 136 if card_data: 137 base_model = card_data.get("base_model") 138 if isinstance(base_model, str): 139 base_model = [base_model] 140 pipeline_tag = card_data.get("pipeline_tag") 141 if tags: 142 tags.append(pipeline_tag) 143 else: 144 tags = [pipeline_tag] 145 if pkg_name := card_data.get("library_name"): 146 if hasattr(PkgType, pkg_name := pkg_name.replace("-", "_").upper()): 147 pkg_type = getattr(PkgType, pkg_name) 148 tokenizer = await model_id.get_cache_path(file_name="tokenizer.json", repo_obj=repo) 149 mir_tags = await model_id.label_model( 150 repo_id=repo.repo_id, 151 base_model=base_model if isinstance(base_model, str) or base_model is None else base_model[0], 152 cue_type=CueType.HUB.value[1], 153 ) 154 tags = card_data.get("tags", []) if card_data else None 155 if mir_tags: 156 if isinstance(mir_tags, list) and isinstance(mir_tags[0], list): 157 mir_bundle = mir_tags if len(mir_tags) > 1 else None 158 dbuq(mir_tags) 159 mir_tag = next(iter(mir_id for mir_id in mir_tags if any(arch for arch in [".dit.", "unet"] if arch in mir_id[0])), mir_tags[0]) 160 else: 161 mir_bundle = None 162 mir_tag = mir_tags 163 base_model = base_model.append(mir_tag[0]) if base_model else [mir_tag[0]] 164 entry_data = await generate_entry(mir_tag=mir_tag, mir_db=mir_db, model_tags=tags) 165 entry_data.setdefault("bundle", mir_bundle) 166 else: 167 mir_tags = [[]] 168 entry_data = { 169 "tags": [], 170 } 171 nfo(mir_tags if mir_tags[0] else f"mir tag not found for {repo.repo_id}") 172 entry = RegistryEntry.create_entry( 173 model=repo.repo_id, 174 size=repo.size_on_disk, 175 cuetype=CueType.HUB, 176 package=pkg_type, 177 model_family=base_model if base_model else [""], 178 path=str(repo.repo_path), 179 api_kwargs=api_data[CueType.HUB.value[1]], # api_data based on package_name (diffusers/mlx_audio) 180 timestamp=int(repo.last_modified), 181 tokenizer=tokenizer, 182 **entry_data, 183 ) 184 entries.append(entry) 185 return entries
Build a registry of models from the local Huggingface Hub cache
Parameters
- mir_db: An existing instance of the MIR database
- api_data: Dictionary of service data pertaining to providers
- entries: Previous registry entries to append
Returns
A list of RegistryEntry elements, or None
188async def ollama_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 189 """Build a registry of models from local Ollama service\n 190 :param mir_db: An existing instance of the MIR database 191 :param api_data: Dictionary of service data pertaining to providers 192 :param entries: Previous registry entries to append 193 :return: A list of RegistryEntry elements, or None""" 194 195 async def generate_cache_data() -> Any: 196 from ollama import ListResponse, show, list as ollama_list 197 198 cache_dir: ListResponse = ollama_list() 199 if cache_dir: 200 for model in cache_dir.models: 201 gguf_data = show(model.model) 202 yield model, gguf_data 203 204 entry_data = {} 205 entries = [] if not entries else entries 206 config = api_data[CueType.OLLAMA.value[1]] 207 async for model, gguf_data in generate_cache_data(): 208 model_id = ModelIdentity() 209 base_model = gguf_data.modelinfo.get("general.architecture") 210 gguf_data = (gguf_data.modelfile,) 211 if hasattr(model, "family") and model.details.family != base_model: 212 base_model = model.details.family 213 if mir_tag := await model_id.label_model(repo_id=model.model, base_model=base_model, cue_type=CueType.OLLAMA.value[1], repo_obj=gguf_data): 214 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, model_tags=[model.details.family]) 215 nfo(f"no tag for {model.model}") if not mir_tag else nfo(f"{mir_tag}") 216 entry = RegistryEntry.create_entry( 217 model=f"{api_data[CueType.OLLAMA.value[1]].get('prefix')}{model.model}", 218 size=model.size.real, 219 model_family=[base_model], 220 cuetype=CueType.OLLAMA, 221 package=PkgType.LLAMA, 222 api_kwargs=config["api_kwargs"], 223 timestamp=int(model.modified_at.timestamp()), 224 tokenizer=None, 225 **entry_data, 226 ) 227 entries.append(entry) 228 return entries
Build a registry of models from local Ollama service
Parameters
- mir_db: An existing instance of the MIR database
- api_data: Dictionary of service data pertaining to providers
- entries: Previous registry entries to append
Returns
A list of RegistryEntry elements, or None
231async def vllm_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 232 """Build a registry of models from local VLLM service\n 233 :param mir_db: An existing instance of the MIR database 234 :param api_data: Dictionary of service data pertaining to providers 235 :param entries: Previous registry entries to append 236 :return: A list of RegistryEntry elements, or None""" 237 238 from openai import OpenAI 239 240 entry_data = {} 241 entries = [] if not entries else entries 242 config = api_data[CueType.VLLM.value[1]] 243 cache_dir = OpenAI(base_url=api_data["VLLM"]["api_kwargs"]["api_base"], api_key=api_data["VLLM"]["api_kwargs"]["api_key"]) 244 for model in cache_dir.models.list().data: 245 model_id = ModelIdentity() 246 id_name = model["data"].get("id") 247 mir_tag = None 248 if id_name: 249 if mir_tag := await model_id.label_model(repo_id=id_name, base_model=None, cue_type=CueType.VLLM.value[1]): 250 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=["text"]) 251 entry = RegistryEntry.create_entry( 252 model=f"{api_data[CueType.VLLM.value[1]].get('prefix')}{id_name}", 253 size=model._data.size_bytes, 254 cuetype=CueType.VLLM, 255 api_kwargs={**config["api_kwargs"]}, 256 timestamp=int(model.modified_at.timestamp()), 257 **entry_data, 258 ) 259 entries.append(entry) 260 return entries
Build a registry of models from local VLLM service
Parameters
- mir_db: An existing instance of the MIR database
- api_data: Dictionary of service data pertaining to providers
- entries: Previous registry entries to append
Returns
A list of RegistryEntry elements, or None
263async def llamafile_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 264 """Build a registry of models from a local Llamafile server\n 265 :param mir_db: An existing instance of the MIR database 266 :param api_data: Dictionary of service data pertaining to providers 267 :param entries: Previous registry entries to append 268 :return: A list of RegistryEntry elements, or None""" 269 from openai import OpenAI 270 271 entry_data = {} 272 mir_tag = None 273 entries = [] if not entries else entries 274 cache_dir: OpenAI = OpenAI(base_url=api_data["LLAMAFILE"]["api_kwargs"]["api_base"], api_key="sk-no-key-required") 275 config = api_data[CueType.LLAMAFILE.value[1]] 276 for model in cache_dir.models.list().data: 277 model_id = ModelIdentity() 278 if hasattr(model, id): 279 if mir_tag := await model_id.label_model(model.id, CueType.LLAMAFILE.value[1]): 280 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=["text"]) 281 entry = RegistryEntry.create_entry( 282 model=f"{api_data[CueType.LLAMAFILE.value[1]].get('prefix')}{model.id}", 283 size=0, 284 cuetype=CueType.LLAMAFILE, 285 api_kwargs=config["api_kwargs"], 286 timestamp=int(model.created), 287 **entry_data, 288 ) 289 entries.append(entry) 290 return entries
Build a registry of models from a local Llamafile server
Parameters
- mir_db: An existing instance of the MIR database
- api_data: Dictionary of service data pertaining to providers
- entries: Previous registry entries to append
Returns
A list of RegistryEntry elements, or None
293async def lm_studio_pool(mir_db: Callable, api_data: Dict[str, Any], entries: List[RegistryEntry]) -> list[RegistryEntry] | None: 294 """Build a registry of models from local LM Studio service\n 295 :param mir_db: An existing instance of the MIR database 296 :param api_data: Dictionary of service data pertaining to providers 297 :param entries: Previous registry entries to append 298 :return: A list of RegistryEntry elements, or None""" 299 300 from lmstudio import LMStudioClient 301 302 entry_data = {} 303 entries = [] if not entries else entries 304 client = LMStudioClient() 305 models = client.list_models() 306 config = api_data[CueType.LM_STUDIO.value[1]] 307 for model in models: 308 model_id = ModelIdentity() 309 tags = [] 310 if hasattr(model, "vision"): 311 tags.extend(["vision", model.vision]) 312 if hasattr(model, "tool_use"): 313 tags.append(["tool", model.tool_use]) 314 mir_tag = None 315 if hasattr(model, "architecture"): 316 if mir_tag := await model_id.label_model(model.architecture, None, CueType.LM_STUDIO.value[1]): 317 entry_data = await generate_entry(mir_tag=mir_tag[0], mir_db=mir_db, tags=tags) 318 entry = RegistryEntry.create_entry( 319 model=f"{api_data[CueType.LM_STUDIO.value[1]].get('prefix')}{model.model_key}", 320 size=model._data.size_bytes, 321 cuetype=CueType.LM_STUDIO, 322 api_kwargs={**config["api_kwargs"]}, 323 timestamp=int(model.modified_at.timestamp()), 324 **entry_data, 325 ) 326 entries.append(entry) 327 return entries
Build a registry of models from local LM Studio service
Parameters
- mir_db: An existing instance of the MIR database
- api_data: Dictionary of service data pertaining to providers
- entries: Previous registry entries to append
Returns
A list of RegistryEntry elements, or None
330async def register_models(data: Optional[Dict[str, Any]] = None) -> list[RegistryEntry] | None: 331 """Retrieve models from ollama server, local huggingface hub cache, local lmstudio cache & vllm.\n 332 :param: data: Testing - Override for API CueType data dictionary 333 我們不應該繼續為LMStudio編碼。 歡迎貢獻者來改進它。 LMStudio is not OSS, but contributions are welcome.""" 334 335 @CUETYPE_CONFIG.decorator 336 async def read_cuetype(data: Optional[Dict[str, Any]] = None) -> dict: 337 return data 338 339 if not data: 340 data = await read_cuetype() 341 342 async def entry_generator(): 343 entry_map = { 344 CueType.HUB.value: hub_pool, 345 CueType.OLLAMA.value: ollama_pool, 346 CueType.LLAMAFILE.value: llamafile_pool, 347 CueType.VLLM.value: vllm_pool, 348 CueType.LM_STUDIO.value: lm_studio_pool, 349 } 350 for cue_type, pool in entry_map.items(): 351 yield cue_type, pool 352 353 entries = [] 354 async for cue_type, provider in entry_generator(): 355 if cue_type[0]: 356 api_data = data 357 entries = await provider(api_data=api_data, mir_db=MIR_DB, entries=entries) 358 359 return sorted(entries, key=lambda x: x.timestamp, reverse=True)
Retrieve models from ollama server, local huggingface hub cache, local lmstudio cache & vllm.
Parameters
- data: Testing - Override for API CueType data dictionary 我們不應該繼續為LMStudio編碼。 歡迎貢獻者來改進它。 LMStudio is not OSS, but contributions are welcome.