refactor(face-restore): drop GFPGAN, ship PhotoMaker-V2 as the sole restore (non-commercial)

Visual review of the GFPGAN-on-cleaned output (9-face grid, 1448x1086) showed it
only polished the already-drifted face without restoring identity — useless for the
"restore who is in the photo" intent. Dropping it.

The shipped restore path is now PhotoMaker-V2, which delivers true identity-from-
embedding face regeneration via a CLIP+ArcFace dual encoder. The ArcFace branch
pulls InsightFace antelopev2/buffalo_l model packs at runtime, which InsightFace
releases under a research-only license, so the whole extra is **NON-COMMERCIAL**.
raiw.cc and any monetized deployment must NOT install the `photomaker` extra.
This is called out at every entry point: CLI flag help, module docstring,
pyproject extra block, CLAUDE.md extras bullet, README install snippet.

Changes:
- Deleted `src/remove_ai_watermarks/face_restore.py` and its tests.
- Deleted the `restore` extra (gfpgan/facexlib/basicsr + scipy<1.18 / numba<0.60
  pins) and the basicsr setuptools<69 build pin from pyproject.toml.
- Restored `src/remove_ai_watermarks/photomaker_restore.py` (V2 this time:
  `TencentARC/PhotoMaker-V2`, `photomaker-v2.bin`, no `pm_version='v1'` override).
- Restored the `photomaker` extra in pyproject with all the upstream-compat
  pins (einops, peft, onnxruntime, insightface) and the `allow-direct-references`
  hatch metadata block.
- `InvisibleEngine` swapped `_restore_faces` -> `_restore_faces_photomaker`;
  `--restore-faces-method` removed (only one method, no choice).
- CLI flag help, CLAUDE.md, README, docs/synthid.md, and
  docs/controlnet-removal-pipeline-research.md all updated.
- docs/synthid-robust-identity-research.md status notice rewritten to list both
  abandoned commercial-safe attempts (V1 + GFPGAN-on-cleaned) and the
  non-commercial trade-off we accepted.

ruff + strict pyright(src/) clean; 578 tests pass (the 9 GFPGAN tests are gone,
the 11 PhotoMaker tests stay green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Victor Kuznetsov
2026-06-08 18:41:01 -07:00
co-authored by Claude Opus 4.8
parent 01fe98bf54
commit 65de8df5c5
13 changed files with 704 additions and 1263 deletions
+26 -24
View File
@@ -76,22 +76,26 @@ lama = [
"onnxruntime>=1.16.0",
"huggingface-hub>=0.20.0",
]
# Optional GFPGAN face-polish post-pass (commercial-safe: GFPGAN Apache-2.0 +
# RetinaFace MIT). Polishes face detail in the DIFFUSION-CLEANED image (not the
# original) using GFPGAN's StyleGAN2 prior, so SynthID is NOT re-introduced -- the
# input pixels GFPGAN derives from are already SynthID-free. This is the shipped path
# because the alternative we wanted (PhotoMaker-V1 identity-as-embedding) has
# significant upstream / diffusers-version compatibility issues; see
# `src/remove_ai_watermarks/face_restore.py` and
# `docs/synthid-robust-identity-research.md`. gfpgan/basicsr/facexlib are an OLD
# ecosystem and pin numpy<2: scipy<1.18 (>=1.18 uses np.long, gone in numpy 1.24-1.26)
# and numba<0.60. Kept OUT of `all` (heavy + model download).
restore = [
"gfpgan>=1.3.8",
"facexlib>=0.3.0",
"basicsr>=1.4.2",
"scipy<1.18",
"numba<0.60",
# **NON-COMMERCIAL.** Optional PhotoMaker-V2 SynthID-robust face-identity post-pass.
# PhotoMaker-V2's ID encoder pulls an InsightFace ArcFace embedding at runtime, and
# the pretrained InsightFace model packs (antelopev2, buffalo_l) are released under a
# non-commercial / research-only license. A paid service (raiw.cc, any monetized SaaS)
# MUST NOT use this extra. See `src/remove_ai_watermarks/photomaker_restore.py` and
# `docs/synthid-robust-identity-research.md`. The PhotoMaker adapter weights
# (photomaker-v2.bin) are Apache-2.0 and download on first use; the InsightFace model
# packs download on first FaceAnalysis() (only triggered inside PhotoMaker's V2 forward).
# Pins beyond the upstream PhotoMaker package itself patch missing declarations that
# would otherwise break the load chain (verified empirically via the Modal cert sweep
# 2026-06-04): einops (used in forward), peft (required by diffusers.fuse_lora),
# onnxruntime (transitive via insightface), and insightface itself (required for the
# package's __init__.py to even import).
photomaker = [
"photomaker @ git+https://github.com/TencentARC/PhotoMaker.git",
"huggingface-hub>=0.20.0",
"einops>=0.7.0",
"insightface>=0.7.3",
"onnxruntime>=1.16.0",
"peft>=0.10.0",
]
# Optional pre-diffusion super-resolution for small inputs (Real-ESRGAN). Loaded via
# spandrel (MIT) -- a pure model-loader with NO basicsr dependency (it pulls only
@@ -121,14 +125,6 @@ all = ["remove-ai-watermarks[gpu,detect,trustmark,lama,dev]"]
[tool.uv]
prerelease = "allow"
# basicsr 1.4.2 (pulled by the `restore` GFPGAN extra) ships sdist-only and its
# setup.py get_version() reads basicsr/version.py in a way that newer setuptools
# (>= 69) breaks with ``KeyError: '__version__'`` under isolated PEP 517 builds.
# Pin an old setuptools as its build dependency so the sdist builds; this is
# scoped to basicsr and does not affect the rest of the resolution.
[tool.uv.extra-build-dependencies]
basicsr = ["setuptools<69"]
# PyTorch Intel-GPU (XPU) wheel index. ``explicit = true`` keeps it inert for
# the default CPU/CUDA install: uv consults it only when a torch install
# explicitly targets it (see the ``gpu`` extra comment), so it does not alter
@@ -159,6 +155,12 @@ Repository = "https://github.com/wiltodelta/remove-ai-watermarks"
requires = ["hatchling<1.31"]
build-backend = "hatchling.build"
# Allow the `photomaker` extra to reference the upstream git URL directly (the
# TencentARC/PhotoMaker package is not on PyPI). The extra itself is NON-COMMERCIAL
# (see the photomaker block above and `photomaker_restore.py`).
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["src/remove_ai_watermarks"]