File size: 4,726 Bytes
1feca1e
40787fc
 
3e805ab
f2a5eb4
 
 
 
 
 
3e805ab
 
1feca1e
aa673de
 
 
 
40787fc
aa673de
 
1feca1e
 
 
 
 
ae5af92
 
1feca1e
3e805ab
1feca1e
3e805ab
7c8c165
3e805ab
1feca1e
40787fc
 
7c8c165
40787fc
1feca1e
40787fc
7c8c165
 
40787fc
 
7c8c165
40787fc
7c8c165
40787fc
 
7c8c165
40787fc
7c8c165
ef87e19
 
7c8c165
1feca1e
7c8c165
1feca1e
 
7c8c165
1feca1e
7c8c165
 
1feca1e
7c8c165
 
40787fc
aa673de
7c8c165
 
1feca1e
7c8c165
 
 
1feca1e
7c8c165
 
aa673de
7c8c165
1feca1e
 
7c8c165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa673de
7c8c165
 
 
 
aa673de
7c8c165
40787fc
9fd6d94
3e805ab
1feca1e
ccf2e38
40787fc
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Dockerfile — Enterprise Lens V4

FROM python:3.10-slim

# ── HF_TOKEN — must be declared immediately after FROM ──────────
# ARG before any RUN step so HF Spaces build secrets are available.
ARG HF_TOKEN=""
ENV HF_TOKEN=${HF_TOKEN}


WORKDIR /app

# ── System deps ───────────────────────────────────────────────────
# g++ / build-essential : required to compile insightface C++ extensions
# libgl1 + libglib2.0-0 : OpenCV headless
# libgomp1              : OpenMP for ONNX runtime
# git + curl            : HF hub downloads
RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        g++ \
        libgl1 \
        libglib2.0-0 \
        libgomp1 \
        git \
        curl \
    && rm -rf /var/lib/apt/lists/*

# ── Python deps ───────────────────────────────────────────────────
COPY requirements.txt .
RUN pip install --no-cache-dir --compile -r requirements.txt

# ── Copy application code ─────────────────────────────────────────
COPY . .

RUN mkdir -p temp_uploads saved_images && chmod -R 777 temp_uploads saved_images

# ── Pre-download public models at BUILD time ──────────────────────
RUN python - <<'EOF'
import os, sys

print("Pre-downloading SigLIP...")
from transformers import AutoProcessor, AutoModel, AutoImageProcessor
AutoProcessor.from_pretrained("google/siglip-base-patch16-224", use_fast=True)
AutoModel.from_pretrained("google/siglip-base-patch16-224")
print("SigLIP done")

print("Pre-downloading DINOv2...")
AutoImageProcessor.from_pretrained("facebook/dinov2-base")
AutoModel.from_pretrained("facebook/dinov2-base")
print("DINOv2 done")

print("Pre-downloading YOLO11n-seg...")
from ultralytics import YOLO
YOLO("yolo11n-seg.pt")
print("YOLO done")

print("Pre-downloading InsightFace buffalo_l...")
import numpy as np
from insightface.app import FaceAnalysis
face_app = FaceAnalysis(name="buffalo_l", providers=["CPUExecutionProvider"])
face_app.prepare(ctx_id=-1, det_size=(640, 640))
face_app.get(np.zeros((112, 112, 3), dtype=np.uint8))
print("InsightFace buffalo_l done")

print("All public models pre-downloaded successfully")
EOF

# ── Pre-download AdaFace (graceful — never fails the build) ───────
RUN python - <<'EOF'
import os, sys, traceback

HF_TOKEN   = os.getenv("HF_TOKEN", "").strip()
REPO_ID    = "minchul/cvlface_adaface_ir50_ms1mv2"
CACHE_PATH = os.path.expanduser("~/.cvlface_cache/minchul/cvlface_adaface_ir50_ms1mv2")

if not HF_TOKEN:
    print("HF_TOKEN not set - skipping AdaFace pre-download")
    print("Fallback: ArcFace zero-padded to 1024-D (build succeeds)")
    sys.exit(0)

try:
    from huggingface_hub import hf_hub_download
    from transformers import AutoModel
    import torch

    print("Pre-downloading AdaFace IR-50 MS1MV2...")
    os.makedirs(CACHE_PATH, exist_ok=True)

    hf_hub_download(repo_id=REPO_ID, filename="files.txt",
        token=HF_TOKEN, local_dir=CACHE_PATH, local_dir_use_symlinks=False)

    with open(os.path.join(CACHE_PATH, "files.txt")) as f:
        extra = [x.strip() for x in f.read().split("\n") if x.strip()]

    for fname in extra + ["config.json", "wrapper.py", "model.safetensors"]:
        fpath = os.path.join(CACHE_PATH, fname)
        if not os.path.exists(fpath):
            print("Downloading " + fname)
            hf_hub_download(repo_id=REPO_ID, filename=fname,
                token=HF_TOKEN, local_dir=CACHE_PATH, local_dir_use_symlinks=False)

    cwd = os.getcwd()
    os.chdir(CACHE_PATH)
    sys.path.insert(0, CACHE_PATH)
    try:
        model = AutoModel.from_pretrained(
            CACHE_PATH, trust_remote_code=True, token=HF_TOKEN)
    finally:
        os.chdir(cwd)
        if CACHE_PATH in sys.path:
            sys.path.remove(CACHE_PATH)

    with torch.no_grad():
        out = model(torch.zeros(1, 3, 112, 112))
    emb = out if isinstance(out, torch.Tensor) else out.embedding
    print("AdaFace done - output dim=" + str(emb.shape[-1]))

except Exception as e:
    print("AdaFace pre-download failed: " + str(e))
    print(traceback.format_exc()[-400:])
    print("Build continues - ArcFace-only fallback active")
    sys.exit(0)
EOF
RUN pip install --no-cache-dir omegaconf
EXPOSE 7860

ENV WEB_CONCURRENCY=1

CMD uvicorn main:app \
        --host 0.0.0.0 \
        --port 7860 \
        --workers ${WEB_CONCURRENCY} \
        --timeout-keep-alive 75