Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ RUN pip install --no-cache-dir --no-build-isolation \
# Copy source.
COPY . .

# Pre-download GFPGAN weights into the image so users don't wait on first run.
RUN python scripts/download_models.py
# Pre-download GFPGAN weights into /refacer/weights/ — a path that is NOT
# volume-mounted at runtime. The models/ volume only needs to contain the
# user-supplied inswapper_128.onnx; mounting it must not shadow these weights.
RUN python scripts/download_models.py --dest /refacer/weights
ENV GFPGAN_MODEL_PATH=/refacer/weights/GFPGANv1.4.pth

# Pre-download InsightFace buffalo_l detection weights into the image.
# This avoids a ~300 MB download on first container start.
Expand Down
4 changes: 3 additions & 1 deletion models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ def load_models(models_dir: str) -> ModelBundle:
If a required library is not installed.
"""
inswapper_path = os.path.join(models_dir, INSWAPPER_FILENAME)
gfpgan_path = os.path.join(models_dir, GFPGAN_FILENAME)
# Allow the GFPGAN weight to live outside models_dir (e.g. baked into a
# Docker image layer that sits beneath a runtime volume mount).
gfpgan_path = os.environ.get("GFPGAN_MODEL_PATH") or os.path.join(models_dir, GFPGAN_FILENAME)

# Validate weights exist before importing heavy libraries
for path, name in [
Expand Down
41 changes: 28 additions & 13 deletions scripts/download_models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import argparse
import os
import urllib.request

REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MODELS_DIR = os.path.join(REPO_ROOT, 'models')
os.makedirs(MODELS_DIR, exist_ok=True)
DEFAULT_DEST = os.path.join(REPO_ROOT, 'models')

MODELS = [
{
Expand All @@ -12,15 +12,30 @@
},
]

for model in MODELS:
dest = os.path.join(MODELS_DIR, model['name'])
if os.path.exists(dest):
print(f"Already exists, skipping: {model['name']}")
continue
print(f"Downloading {model['name']}...")
urllib.request.urlretrieve(model['url'], dest)
print(f"Saved to {dest}")

print("\nNote: inswapper_128.onnx must be downloaded manually from:")
print("https://drive.google.com/file/d/1krOLgjW2tAPaqV-Bw4YALz0xT5zlb5HF/view")
print(f"Place it in: {MODELS_DIR}")
def download(dest: str) -> None:
os.makedirs(dest, exist_ok=True)
for model in MODELS:
path = os.path.join(dest, model['name'])
if os.path.exists(path):
print(f"Already exists, skipping: {model['name']}")
continue
print(f"Downloading {model['name']}...")
urllib.request.urlretrieve(model['url'], path)
print(f"Saved to {path}")

print("\nNote: inswapper_128.onnx must be downloaded manually from:")
print("https://drive.google.com/file/d/1krOLgjW2tAPaqV-Bw4YALz0xT5zlb5HF/view")
print(f"Place it in: {DEFAULT_DEST}")


if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Download Refacer model weights.")
parser.add_argument(
'--dest',
default=DEFAULT_DEST,
metavar='DIR',
help='Directory to save weights into (default: models/ in the repo root).',
)
args = parser.parse_args()
download(args.dest)
Loading