--- name: models_auto_download_fallback overview: 为分类服务(Fashion-CLIP)与抠图服务(BiRefNet)统一改造模型加载逻辑:启动时先尝试完全离线加载本地缓存,本地不存在则自动联网下载;同时统一两个服务的 HF 镜像配置。 todos: - id: matting-two-level-loading content: 改造抠图服务 main.py(镜像、日志、绝对路径 cache_dir、两级加载)并同步 requirements.txt 注释 status: completed - id: classification-two-level-loading content: 改造分类服务 main.py(镜像统一 hf-mirror.com、模型与处理器两级加载) status: completed - id: syntax-verify content: 对两个 main.py 执行 py_compile 语法验证并清理 __pycache__ status: completed dependencies: - matting-two-level-loading - classification-two-level-loading --- ## 产品概述 对两个纯 Python AI 服务(衣物分类服务 Fashion-CLIP、抠图服务 BiRefNet)的模型加载逻辑统一改造:启动时先检查本地缓存,本地已存在则完全离线加载(零网络请求);本地不存在或不完整时自动联网下载模型到本地缓存,下载完成后后续启动均走离线分支。 ## 核心功能 - **抠图服务改造**:新增国内镜像与日志模块,模型缓存目录改为绝对路径(消除启动工作目录依赖),模型加载改为「本地存在则离线、不存在则自动下载」两级模式,并同步更新 requirements.txt 注释说明 - **分类服务改造**:镜像地址统一为 hf-mirror.com(与代码注释保持一致),模型与处理器加载改为同一套「本地存在则离线、不存在则自动下载」两级模式 - **运行行为**:首次启动无缓存时自动下载(走国内镜像加速),有缓存后完全离线;日志明确区分「命中本地缓存」与「自动下载」两种路径 ## 技术栈 - Python 3 + HuggingFace Transformers(CLIPModel / CLIPProcessor / AutoModelForImageSegmentation) - 国内镜像 hf-mirror.com(通过 HF_ENDPOINT 环境变量,在 import transformers 之前设置) - 依赖与 FastAPI 服务结构不变,仅改模型加载段 ## 实现方案 ### 统一两级加载模式 利用 `local_files_only=True` 的行为特性:本地缓存缺失或不完整时 huggingface_hub 抛出 `OSError`(Python 3 中 `LocalEntryNotFoundError` 是 `OSError` 子类)或 `ValueError`,捕获后回退联网下载。两级使用同一个 cache_dir,HF 缓存结构固定(`models--repo/snapshots/...`),无需手动判断目录结构: ```python try: model = XXX.from_pretrained(REPO, ..., local_files_only=True, cache_dir=CACHE_DIR) logger.info("模型命中本地缓存,离线加载") except (OSError, ValueError) as e: logger.info(f"本地未找到模型缓存,自动下载 ... ({e})") model = XXX.from_pretrained(REPO, ..., cache_dir=CACHE_DIR) ``` ### 抠图服务 `thirdparty/matting_server/main.py` 1. 顶部(import transformers 之前)加镜像设置:`if "HF_ENDPOINT" not in os.environ: os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"`,并补 `import os` 2. 新增 `logging.basicConfig(level=logging.INFO)` + `logger = logging.getLogger(__name__)` 3. 模型缓存目录改为绝对路径:`_model_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "model")`,替换原相对路径 `cache_dir="./model"` 4. 模型加载改为两级加载(保持 `trust_remote_code=True`;`model.eval()`、device 判定、CUDA `model.half()` 逻辑保持不变) 5. 同目录 `requirements.txt` 注释同步:模型首次启动自动下载到本目录 `./model/` 缓存,无需手动放置 ### 分类服务 `thirdparty/classification_server/main.py` 1. 第 21 行镜像从 `https://hf-api.gitee.com` 改为 `https://hf-mirror.com`(与第 12 行 docstring 一致) 2. 第 450-451 行 model 与 processor 放入同一 try 块两级加载:`local_files_only=True` 先试,任一失败则整体回退联网下载;`model = model.to(device)`、`model.eval()`、CUDA `half()` 保持原位置 ### 性能与可靠性 - 有缓存时零网络请求,启动时间不受网络影响;无缓存时仅首次下载(约 400MB,走镜像) - 缓存不完整(下载中断)时第一级失败自动触发补齐,天然容错 - 日志两条路径可观测,便于运维确认模型来源 ## 目录结构 ``` thirdparty/ ├── classification_server/ │ ├── main.py # [MODIFY] 镜像统一 hf-mirror.com;模型/处理器两级加载 │ └── requirements.txt # 不变 └── matting_server/ ├── main.py # [MODIFY] 新增镜像/日志;cache_dir 绝对路径;模型两级加载 └── requirements.txt # [MODIFY] 注释更新为自动下载说明 ``` ## 验证方式 - 两个文件 `python3 -m py_compile` 语法验证,验证后清理 `__pycache__` - 交付说明:首次启动自动下载(走 hf-mirror 镜像),有缓存后完全离线;日志区分「命中本地缓存」与「自动下载」