AsianPlayer's picture
download
raw
4.33 kB
"""cwm3/baselines_dms/of3_compat.py — the four adaptations that make `openface-test` 0.1.26 (OpenFace 3.0) run inside the hci env
(torch 2.9 cu128 / numpy 2.2 / scipy 1.15 / timm 1.0.27) without honouring its downgrading pins. Call apply() BEFORE importing
openface, or use load() which does both. Nothing about the networks or weights is changed.
1. scipy.integrate.simps -> alias of simpson (removed in scipy >= 1.14; STAR/lib/metric/fr_and_auc.py imports it at module load)
2. cfg_mnet["pretrain"] = False (RetinaFace(cfg, phase='test') would torch.load a CWD-relative ./weights/mobilenetV1X0.25_pretrain.tar
to initialise the MobileNet backbone; the full detector state dict Alignment_RetinaFace.pth is loaded right after — 300/300 keys — so
the backbone init is redundant. The tar is nevertheless kept in weights/openface3/ for completeness.)
3. STAR conf Base.init_instance -> no-op (upstream hard-codes ckpt_dir='/work/jiewenh/openFace/OpenFace-3.0/STAR' and opens a
tensorboardX SummaryWriter + log.txt under it -> PermissionError here; inference never uses them)
4. LandmarkDetector on CUDA requires device_ids=[<index>] (its default [-1] raises) — load() passes it.
5. LandmarkDetector's public constructor always builds the STAR *WFLW* config (98 points), so Landmark_68.pkl fails with size
mismatches; landmark_detector(landmarks=68) injects data_definition='300W' (classes_num [68, 9, 68]) through utility.get_config.
"""
from __future__ import annotations
import warnings
from pathlib import Path
from baselines_dms import registry as R
_APPLIED = False
def apply() -> None:
global _APPLIED
if _APPLIED:
return
import scipy.integrate as _si
if not hasattr(_si, "simps"):
_si.simps = _si.simpson # (1)
from openface.Pytorch_Retinaface.data import cfg_mnet
cfg_mnet["pretrain"] = False # (2)
from openface.STAR.conf import base as _base
def _init_instance(self): # (3)
self.writer = None
self.logger = None
for _c in list(vars(_base).values()):
if isinstance(_c, type) and hasattr(_c, "init_instance"):
_c.init_instance = _init_instance
_APPLIED = True
def landmark_detector(device: str = "cuda", landmarks: int = 98, weights_dir: Path | None = None):
"""STAR LandmarkDetector for Landmark_98.pkl (WFLW, 98 pts) or Landmark_68.pkl (300W, 68 pts) — adaptation (5)."""
apply()
import openface.landmark_detection as LDM
from openface.STAR.lib import utility
dd = {98: "WFLW", 68: "300W"}[landmarks]
w = Path(weights_dir) if weights_dir else R.resolve("openface3")
dev = "cuda" if str(device).startswith("cuda") else "cpu"
idx = int(str(device).split(":")[1]) if ":" in str(device) else 0
orig = utility.get_config
def patched(args):
args.data_definition = dd
return orig(args)
utility.get_config = patched
try:
return LDM.LandmarkDetector(model_path=str(w / f"Landmark_{landmarks}.pkl"), device=dev, device_ids=[idx] if dev == "cuda" else [-1]) # (4)
finally:
utility.get_config = orig
def load(device: str = "cuda", weights_dir: Path | None = None, landmarks: int = 98):
"""Return (FaceDetector, LandmarkDetector, MultitaskPredictor) built on the registry-verified OpenFace 3.0 weights."""
apply()
warnings.filterwarnings("ignore", category=FutureWarning)
from openface.face_detection import FaceDetector
from openface.multitask_model import MultitaskPredictor
w = Path(weights_dir) if weights_dir else R.resolve("openface3")
dev = "cuda" if str(device).startswith("cuda") else "cpu"
fd = FaceDetector(model_path=str(w / "Alignment_RetinaFace.pth"), device=dev)
ld = landmark_detector(device=device, landmarks=landmarks, weights_dir=w)
mt = MultitaskPredictor(model_path=str(w / "MTL_backbone.pth"), device=dev)
return fd, ld, mt
EMOTIONS = ("Neutral", "Happy", "Sad", "Surprise", "Fear", "Disgust", "Anger", "Contempt") # README table, AffectNet order
OUTPUT_FIELDS = ("face_detection", "landmarks", "emotion", "gaze_yaw", "gaze_pitch", "action_units") # openface CLI / demo.py TSV columns

Xet Storage Details

Size:
4.33 kB
·
Xet hash:
91dab60bc4845569677ebc711573f605243a7fada012682950c514ec3aebf4b8

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.