sources/webrtc-reviewed/src_llm/utils/model_downloader.py

Текстовый файл из учебного комплекта, не свидетельство установленного runtime. Вернуться к учебнику · Исходный файл

   1 from __future__ import annotations
   2 
   3 from fnmatch import fnmatch
   4 from pathlib import Path
   5 from typing import Iterable
   6 
   7 from huggingface_hub import HfApi, hf_hub_download
   8 
   9 GGUF_PATTERNS = ("*.gguf",)
  10 
  11 
  12 def ensure_model_path(
  13     model_id: str,
  14     models_dir: str,
  15     model_file: str | None = None,
  16 ) -> str:
  17     # If model_id is a path, return it as-is.
  18     p = Path(model_id)
  19     if p.exists():
  20         return str(p.resolve())
  21 
  22     # Resolve relative paths from the current working directory.
  23     models_dir = Path(models_dir).expanduser().resolve()
  24     target_dir = models_dir / _slug(model_id)
  25     target_dir.mkdir(parents=True, exist_ok=True)
  26 
  27     # Pick the model file.
  28     filename = model_file or _select_model_file(model_id)
  29     cached = target_dir / filename
  30     if cached.exists():
  31         return str(cached.resolve())
  32 
  33     # Download the model.
  34     downloaded = hf_hub_download(
  35         repo_id=model_id,
  36         filename=filename,
  37         local_dir=str(target_dir),
  38         local_dir_use_symlinks=False,
  39     )
  40 
  41     return str(Path(downloaded).resolve())
  42 
  43 
  44 
  45 def _select_model_file(repo_id: str) -> str:
  46     candidates = list(_list_repo_files(repo_id))
  47     if not candidates:
  48         raise ValueError(f"No GGUF files found for repo {repo_id}")
  49 
  50     candidates.sort(key=lambda item: (item.size or 0, item.rfilename))
  51     return candidates[0].rfilename
  52 
  53 
  54 def _list_repo_files(repo_id: str) -> Iterable:
  55     api = HfApi()
  56     info = api.repo_info(repo_id, files_metadata=True)
  57     if not info.siblings:
  58         return []
  59 
  60     for sibling in info.siblings:
  61         path = sibling.rfilename
  62         if sibling.size is None:
  63             continue
  64         if any(fnmatch(path, pattern) for pattern in GGUF_PATTERNS):
  65             yield sibling
  66 
  67 
  68 def _slug(value: str) -> str:
  69     return "".join(ch if ch.isalnum() else "_" for ch in value)