feat(photo-ai): официальный CodeFormer вендорен, веса на этапе сборки
CodeFormer был написан по API сторонней обёртки с PyPI (rohitkhatri): CodeFormer(..., device=..., fp16=False) и net.device официальный класс не принимает — вызов падал бы с TypeError. В photo-ai/vendor/codeformer вендорен официальный sczhou/CodeFormer (codeformer_arch.py + vqgan_arch.py, b33cc7d, лицензия S-Lab 1.0), устройство передаётся через net.to(device), чекпоинт читается из params_ema. Веса больше не качаются лениво при первом запросе: fetch-weights.py на сборке образа кладёт их в /opt/photo-ai-seed (build-arg PHOTO_AI_PREFETCH, дефолт codeformer), при старте seed_weights() переносит их в том photo-ai-models:/models/weights. Том переживает пересборку образа, BuildKit-кэш не даёт качать повторно, недоступная сеть на сборке не роняет образ.
This commit is contained in:
+21
-12
@@ -171,20 +171,29 @@
|
||||
сейчас скачиваются мимо тома и теряются при пересборке. Свой `FaceRestoreHelper`/каталог
|
||||
`/models/weights` — обязательное требование этапа.
|
||||
|
||||
- [x] **D5. CodeFormer — опционален по умолчанию.** Проверено 2026-09-28: на PyPI есть только
|
||||
сторонняя обёртка `codeformer 0.0.11` (`github.com/rohitkhatri/codeformer`, тянет `lpips`) —
|
||||
это не официальный `sczhou/CodeFormer`, использовать его не будем. Официальные веса доступны.
|
||||
Решение: официальный модуль вендорится в `photo-ai/vendor/codeformer/` **только если** face-режим
|
||||
CodeFormer реально понадобится; в рамках текущего плана не вендорим, дефолт
|
||||
`PHOTO_AI_FACE_MODEL=gfpgan` (Stage 1–3), чтобы дефолтный путь работал без вендоринга.
|
||||
- `FACE_REGISTRY` всегда содержит обе записи, но запись `codeformer` активна только если
|
||||
`import codeformer` (с `photo-ai/vendor` в `sys.path`) успешен.
|
||||
- Нет модуля → запись не попадает в `face_models` в `/health` и в список `/models`, UI её не показывает,
|
||||
`POST /enhance` с `face_model=codeformer` → `400` с текстом «CodeFormer не установлен в образ,
|
||||
доступен gfpgan». Сборка и CPU-режим не падают.
|
||||
- [x] **D5. CodeFormer — вендорен, веса тянутся на сборке.** Первоначально (проверено 2026-09-28) на PyPI
|
||||
есть только сторонняя обёртка `codeformer 0.0.11` (`github.com/rohitkhatri/codeformer`, тянет
|
||||
`lpips`) — это не официальный `sczhou/CodeFormer`, использовать его не будем.
|
||||
**Обновлено 2026-10-04:** официальный модуль вендорен в `photo-ai/vendor/codeformer/`
|
||||
(`codeformer_arch.py` + `vqgan_arch.py`, коммит `b33cc7d`, лицензия S-Lab 1.0 рядом).
|
||||
`basicsr==1.4.2` с PyPI не содержит ни `vqgan_arch.py`, ни `codeformer_arch.py`, поэтому
|
||||
вендорится **оба** файла, а импорт в `codeformer_arch.py` переведён на относительный.
|
||||
Дефолтом остаётся `PHOTO_AI_FACE_MODEL=gfpgan`, но `codeformer` теперь работает сразу.
|
||||
- `FACE_REGISTRY` всегда содержит обе записи, запись `codeformer` активна, если `import codeformer`
|
||||
(с `photo-ai/vendor` в `sys.path`) успешен.
|
||||
- **`build_face_codeformer` пришлось чинить.** Код был написан по API обёртки rohitkhatri:
|
||||
`CodeFormer(..., device=..., fp16=False)` и `net.device` официальный класс не принимает —
|
||||
вызов падал бы с `TypeError`/`AttributeError`. Официальная сигнатура:
|
||||
`(dim_embd, n_head, n_layers, codebook_size, latent_size, connect_list, fix_modules, vqgan_path)`.
|
||||
Теперь устройство передаётся через `net.to(device)`. Чекпоунт официальных весов лежит под
|
||||
ключом `params_ema` — учтено в `build_face_codeformer`.
|
||||
- `strength` валиден только для CodeFormer: при `face_model=gfpgan` и `strength`, отличном от 0.7,
|
||||
→ `400` с пояснением, иначе параметр молча игнорировался бы.
|
||||
- Веса CodeFormer качаются тем же загрузчиком в `/models/weights/codeformer.pth`.
|
||||
- **Веса больше не качаются лениво.** `photo-ai/fetch-weights.py` на этапе сборки кладёт их в
|
||||
`/opt/photo-ai-seed` (build-arg `PHOTO_AI_PREFETCH`, дефолт `codeformer`; `face`/`all`/`none`),
|
||||
при старте `seed_weights()` переносит их в том `photo-ai-models:/models/weights`. Том
|
||||
переживает пересборку образа, BuildKit-кэш не даёт перекачивать. Если весов нет ни в томе,
|
||||
ни в seed — работает прежний ленивый загрузчик.
|
||||
|
||||
- [x] **D6. Поведение без `photo-ai` в compose.** Сейчас `PHOTO_AI_URL` по умолчанию
|
||||
`http://photo-ai:8080` (`docker-compose.yml:79`) — то есть «ИИ» включён по умолчанию.
|
||||
|
||||
Reference in New Issue
Block a user