Текстовый файл из учебного комплекта, не свидетельство установленного 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)