尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【Bug已解决】Loading repository after rename does not work (with old name) 解决方案

【Bug已解决】Loading repository after rename does not work (with old name) 解决方案 【Bug已解决】Loading repository after rename does not work (with old name) 解决方案一、现象长什么样你把 HF Hub 上的模型仓库从old-org/old-name改名成new-org/new-name然后代码里还用旧名加载结果失败# 现象 A旧名直接 401/404 Repository Not Found: 401 Client Error. (Request ID: ...) old-org/old-name # 改名后旧名不再解析from_pretrained 用旧名去 Hub 查 - 404/401 # 现象 B本地缓存按旧名组织改名后读不到 OSError: Cant find old-org/old-name in the cached model list. # 缓存目录是 .../models--old-org--old-name/改名后新名对应新目录 # 旧缓存没被复用 # 现象 C重定向没生效部分版本 # Hub 改名应返回 redirect 到新名但某些 huggingface_hub 版本/网络下 # 重定向没被正确跟随旧名加载静默失败 # 典型触发 from transformers import AutoModel m AutoModel.from_pretrained(old-org/old-name) # 改名后失败最典型的指纹仓库改名后用旧名from_pretrained不再工作要么 404、要么缓存读不到、要么重定向没生效。二、背景HF Hub 的仓库改名rename机制改名后旧名应当通过 Hub 的**重定向redirect**解析到新名类似网页永久重定向。huggingface_hub的model_info/hf_hub_download在拿到旧名时应当请求旧名 → Hub 返回重定向302/新名跟随重定向 → 用新名下载/查信息本地缓存按规范名新名组织旧名作为别名。但实际中改名加载失败的常见原因缓存键是旧名本地~/.cache/huggingface下是models--old-org--old-name改名后新会话用新名产生models--new-org--new-name旧缓存不被复用现象 B。重定向在某些路径没被跟随from_pretrained内部先用model_info(old_name)拿 config若model_info这步没跟随重定向或被缓存的 404 拦截后续下载全失败现象 A/C。验证/鉴权绑定旧名某些 gated repo 的访问令牌与旧名关联改名后旧名 401现象 A。三、根因根因有三类改名重定向未被from_pretrained全路径跟随。from_pretrained先model_info(repo_id)再下载。若model_info旧名返回 404重定向在某些 hub 版本默认不跟随整条链失败而不是自动换新名。本地缓存按旧名隔离旧缓存不复用。 Hub 缓存用models--repo_id 规范名--目录。改名后规范名变了旧缓存目录models--old--old与新名models--new--new不共享即使权重完全相同也要重新下载浪费带宽或旧名加载直接找不到。旧名被缓存为不存在。 若之前用旧名查询过并得到 404结果可能被短时缓存改名后重定向已生效但客户端仍读缓存的 404 → 现象 A 持续。四、最小可运行复现下面用纯 Python 模拟旧名查询重定向未跟随则 404跟随则解析到新名from typing import Dict, Optional # 模拟 Hub旧名 - 重定向到新名 REDIRECTS {old-org/old-name: new-org/new-name} CACHE {} # repo_id - 是否已下载 def model_info(repo_id: str, follow_redirect: bool False): if repo_id in REDIRECTS: if follow_redirect: return {id: REDIRECTS[repo_id], redirected_from: repo_id} else: return {error: 404 Not Found, id: repo_id} return {id: repo_id} def from_pretrained_buggy(repo_id: str): 有 bug不跟随重定向。 info model_info(repo_id, follow_redirectFalse) if error in info: raise FileNotFoundError(fCant load {repo_id}: {info[error]}) return floaded {info[id]} def from_pretrained_fixed(repo_id: str): 修正跟随重定向到新名。 info model_info(repo_id, follow_redirectTrue) if error in info: raise FileNotFoundError(fCant load {repo_id}) return floaded {info[id]} # 复现不跟随重定向 - 404 try: from_pretrained_buggy(old-org/old-name) print(复现失败) except FileNotFoundError as e: print(复现成功(根因):, e) # 修正跟随重定向 - 新名加载成功 print(from_pretrained_fixed(old-org/old-name)) # loaded new-org/new-name运行后buggy 版因不跟随重定向而 404fixed 版跟随重定向解析到新名复现并修复了根因 1。五、解决方案第一层最小直接修复最快的止血在调用from_pretrained前先解析仓库的新名跟随重定向用新名加载或显式用新名from huggingface_hub import model_info, HfApi def resolve_repo_id(repo_id: str) - str: 第一层修复跟随改名重定向返回当前规范名。 try: info model_info(repo_id, tokenTrue, files_metadataFalse) # model_info 在 hub 支持改名重定向时返回对象的 id 已是新名 return getattr(info, id, repo_id) except Exception: # 若 model_info 仍 404尝试用 api 的 repo 查找 return repo_id # 使用改名后用解析出的新名加载 resolved resolve_repo_id(old-org/old-name) model AutoModel.from_pretrained(resolved) # 或者最简单直接改代码用新名推荐最稳 model AutoModel.from_pretrained(new-org/new-name)第一层让用户立刻能加载改名后的仓库跟随重定向或用新名不再 404。六、解决方案第二层结构性改进用RepoRenameResolver把旧名→新名解析 缓存复用 重定向容错收口from dataclasses import dataclass from typing import Dict, Optional dataclass class RepoRenameResolver: 处理 Hub 仓库改名解析新名、复用旧缓存、容错重定向。 redirect_cache: Dict[str, str] None def __post_init__(self): self.redirect_cache {} def resolve(self, repo_id: str) - str: if repo_id in self.redirect_cache: return self.redirect_cache[repo_id] # 跟随重定向解析hub 返回的新名 try: from huggingface_hub import model_info info model_info(repo_id, tokenTrue) new_id getattr(info, id, repo_id) if new_id ! repo_id: self.redirect_cache[repo_id] new_id return new_id except Exception: return repo_id def cached_path_for(self, repo_id: str) - str: # 缓存目录按规范名解析后的新名组织旧名别名也指向它 new self.resolve(repo_id) return fmodels--{new.replace(/, --)}-- # 使用 resolver RepoRenameResolver() new resolver.resolve(old-org/old-name) print(解析到:, new, 缓存目录:, resolver.cached_path_for(old-org/old-name)) model AutoModel.from_pretrained(new)RepoRenameResolver的语义是仓库名应以规范名新名为准旧名只是别名解析一次后缓存加载与缓存都走新名避免重复下载与 404。七、解决方案第三层断言 / CI 守护用 pytest 固化旧名能被解析到新名、缓存复用、重定向容错import pytest def test_old_name_resolves_to_new(monkeypatch): from repo_rename import RepoRenameResolver # 模拟 model_info 返回新名重定向生效 class FakeInfo: id new-org/new-name monkeypatch.setattr(huggingface_hub.model_info, lambda *a, **k: FakeInfo()) r RepoRenameResolver() assert r.resolve(old-org/old-name) new-org/new-name def test_redirect_cached(): from repo_rename import RepoRenameResolver calls {n: 0} class FakeInfo: id new-org/new-name import huggingface_hub orig huggingface_hub.model_info def fake(*a, **k): calls[n] 1 return FakeInfo() huggingface_hub.model_info fake try: r RepoRenameResolver() r.resolve(old-org/old-name) r.resolve(old-org/old-name) # 第二次应命中缓存 finally: huggingface_hub.model_info orig assert calls[n] 1, 重定向结果应被缓存避免重复查询 def test_cache_path_uses_new_name(): from repo_rename import RepoRenameResolver r RepoRenameResolver() r.redirect_cache[old-org/old-name] new-org/new-name assert r.cached_path_for(old-org/old-name) models--new-org--new-name--CI 跑pytest tests/test_repo_rename.py以后只要有人又用旧名硬编码加载不解析重定向测试可提示改为解析新名。八、排查清单当改名后旧名加载失败按顺序查401/404 Not Found→ 旧名重定向没被跟随用resolve解析到新名再加载。本地缓存读不到 → 缓存按旧名隔离用新名加载会复用或重新下载旧缓存可手动软链到新名目录。之前查过旧名得到 404 被短时缓存 → 清掉huggingface_hub的查询缓存或换新名。gated repo 改名后旧令牌 401 → 去 Hub 重新授权令牌绑定新名。长期方案用RepoRenameResolver统一旧名→新名解析 缓存复用代码里用新名。九、小结Loading repository after rename does not work (with old name) 的根因是仓库改名后旧名依赖 Hub 的重定向解析到新名但from_pretrained的某些路径不跟随重定向直接 404、本地缓存按旧名隔离不复用、旧名的 404 查询被缓存于是旧名加载失败。第一层加载前用model_info跟随重定向解析出新名或直接改用新名立刻能加载。第二层用RepoRenameResolver把旧名→新名解析 缓存按新名复用收口避免重复下载与 404。第三层pytest 断言旧名解析到新名、重定向缓存、缓存路径用新名防止回归。记住仓库改名后规范名新名才是真相代码里应当用新名或用重定向解析器把旧名翻译成新名——不要硬编码已失效的旧名。
返回列表