ProxyPlayground / src /embeddings.py
niftym's picture
Add proxy playground app
e967c28 verified
Raw History Blame Contribute Delete
2.53 kB
"""
CLIP + face embeddings. Same models/config as your Embedding_expansion
notebook: CLIP ViT-H-14 (laion2b_s32b_b79k, 1024-d, L2-normalized) and
InsightFace buffalo_l (512-d). Lazily loaded once on first use instead
of at notebook-cell/import time, since a Gradio app shouldn't pay this
cost unless Part 2 is actually run.
"""
import numpy as np
import torch
CLIP_MODEL_NAME = "ViT-H-14"
CLIP_PRETRAINED = "laion2b_s32b_b79k"
CLIP_DIM = 1024
FACE_DIM = 512
_clip_model = None
_clip_preprocess = None
_device = None
_face_app = None
def _get_device():
global _device
if _device is None:
_device = "cuda" if torch.cuda.is_available() else "cpu"
return _device
def _get_clip():
global _clip_model, _clip_preprocess
if _clip_model is None:
import open_clip
device = _get_device()
_clip_model, _, _clip_preprocess = open_clip.create_model_and_transforms(
CLIP_MODEL_NAME, pretrained=CLIP_PRETRAINED
)
_clip_model = _clip_model.to(device).eval()
return _clip_model, _clip_preprocess
def _get_face_app():
global _face_app
if _face_app is None:
from insightface.app import FaceAnalysis
_face_app = FaceAnalysis(
name="buffalo_l",
providers=["CUDAExecutionProvider", "CPUExecutionProvider"],
)
_face_app.prepare(ctx_id=0, det_size=(640, 640))
return _face_app
@torch.no_grad()
def embed_clip(pil_image):
"""Returns a (1024,) float32 L2-normalized CLIP embedding."""
model, preprocess = _get_clip()
x = preprocess(pil_image).unsqueeze(0).to(_get_device())
f = model.encode_image(x)
f = f / f.norm(dim=-1, keepdim=True)
return f.squeeze(0).cpu().numpy().astype(np.float32)
def embed_face(pil_image):
"""
Returns (emb, det_score, bbox_xywh, n_faces, status).
status: "ok" | "ok_multi" (largest face used) | "no_face"
"""
face_app = _get_face_app()
rgb = np.array(pil_image.convert("RGB"))
bgr = rgb[:, :, ::-1].copy()
faces = face_app.get(bgr)
if not faces:
return None, None, None, 0, "no_face"
def area(f):
x1, y1, x2, y2 = f.bbox
return (x2 - x1) * (y2 - y1)
face = max(faces, key=area) if len(faces) > 1 else faces[0]
emb = face.normed_embedding.astype(np.float32)
x1, y1, x2, y2 = [float(v) for v in face.bbox]
bbox = [x1, y1, x2 - x1, y2 - y1]
status = "ok" if len(faces) == 1 else "ok_multi"
return emb, float(face.det_score), bbox, len(faces), status