84 lines
5.0 KiB
Markdown
84 lines
5.0 KiB
Markdown
---
|
||
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 镜像),有缓存后完全离线;日志区分「命中本地缓存」与「自动下载」 |