Buckets:
| """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.