Summary
• Implemented global offline mode for all HuggingFace-dependent modules to eliminate unauthenticated request warnings and prevent external connection attempts during startup and runtime. Changes • Global Offline Configuration: Added HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1 to the environment variables at the top of edit_api.py, embeddings.py, watcher.py, and pose_llm/pose_llm_api.py. • Explicit Local Files Only: Updated all huggingface_hub.hf_hub_download calls in edit_api.py to include local_files_only=True, ensuring they never attempt to reach the Hub if models are already cached. • LLM Service Optimization: Updated AutoTokenizer and AutoModelForCausalLM calls in pose_llm/pose_llm_api.py to use local_files_only=True. • Consistency: Ensured that shared modules like embeddings.py which uses open_clip are also locked to offline mode to prevent background downloads.
This commit is contained in:
@@ -10,6 +10,8 @@ Run ComfyUI first (run_comfyui.sh), then this service (start_api.sh).
|
||||
|
||||
import io
|
||||
import os
|
||||
os.environ["HF_HUB_OFFLINE"] = "1"
|
||||
os.environ["TRANSFORMERS_OFFLINE"] = "1"
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
@@ -450,6 +452,12 @@ def on_startup():
|
||||
print(f"[output] mount warning: {e}")
|
||||
# Write initial static data files (synchronous — ensures files exist before first request)
|
||||
_write_all_static()
|
||||
# Trigger pose index backfill
|
||||
try:
|
||||
if _load_pose_estimator():
|
||||
build_pose_index()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# --- helpers ----------------------------------------------------------------
|
||||
@@ -568,7 +576,7 @@ def _load_tagger():
|
||||
cfg = resolve_data_config(model.pretrained_cfg, model=model)
|
||||
transform = create_transform(**cfg)
|
||||
|
||||
lpath = huggingface_hub.hf_hub_download(WD_MODEL, "selected_tags.csv")
|
||||
lpath = huggingface_hub.hf_hub_download(WD_MODEL, "selected_tags.csv", local_files_only=True)
|
||||
with open(lpath, newline="") as f:
|
||||
rows = list(csv.DictReader(f))
|
||||
# category 0=general 4=character 9=rating
|
||||
@@ -664,6 +672,7 @@ def _load_faceswapper():
|
||||
model_path = huggingface_hub.hf_hub_download(
|
||||
'deepinsight/inswapper', 'inswapper_128.onnx',
|
||||
local_dir=os.path.dirname(model_path),
|
||||
local_files_only=True
|
||||
)
|
||||
print(f"[faceswap] Downloaded inswapper_128.onnx to {model_path}")
|
||||
except Exception as de:
|
||||
@@ -1294,24 +1303,36 @@ _privacy_lock = threading.Lock()
|
||||
|
||||
|
||||
def _privacy_monitor_daemon():
|
||||
"""Monitors GNOME screen lock via D-Bus gdbus monitor."""
|
||||
"""Monitors GNOME/Freedesktop screen lock via D-Bus gdbus monitor."""
|
||||
global _privacy_locked
|
||||
print("[privacy] Starting monitor daemon...")
|
||||
# Monitor ScreenSaver state changes
|
||||
cmd = ["gdbus", "monitor", "--session", "--dest", "org.gnome.ScreenSaver", "--object-path", "/org/gnome/ScreenSaver"]
|
||||
try:
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
||||
for line in proc.stdout:
|
||||
# Lines look like: /org/gnome/ScreenSaver: org.gnome.ScreenSaver.ActiveChanged (true,)
|
||||
if "ActiveChanged" in line:
|
||||
is_locked = "(true,)" in line
|
||||
with _privacy_lock:
|
||||
if _privacy_locked != is_locked:
|
||||
_privacy_locked = is_locked
|
||||
print(f"[privacy] System lock state change detected: {is_locked}")
|
||||
_write_all_static()
|
||||
except Exception as e:
|
||||
print(f"[privacy] Monitor error (is gdbus installed?): {e}")
|
||||
|
||||
# We try to monitor both GNOME and Freedesktop ScreenSaver
|
||||
destinations = [
|
||||
("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver"),
|
||||
("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver")
|
||||
]
|
||||
|
||||
def monitor(dest, obj_path):
|
||||
global _privacy_locked
|
||||
cmd = ["gdbus", "monitor", "--session", "--dest", dest, "--object-path", obj_path]
|
||||
try:
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
||||
for line in proc.stdout:
|
||||
# GNOME: ActiveChanged (true,) or (false,)
|
||||
# Freedesktop: Locked or ActiveChanged
|
||||
if "ActiveChanged" in line or "Locked" in line:
|
||||
is_locked = "(true,)" in line or "true" in line.lower()
|
||||
with _privacy_lock:
|
||||
if _privacy_locked != is_locked:
|
||||
_privacy_locked = is_locked
|
||||
print(f"[privacy] System lock state change detected via {dest}: {is_locked}")
|
||||
_write_all_static()
|
||||
except Exception as e:
|
||||
print(f"[privacy] Monitor error for {dest}: {e}")
|
||||
|
||||
for dest, path in destinations:
|
||||
threading.Thread(target=monitor, args=(dest, path), daemon=True).start()
|
||||
|
||||
|
||||
def _write_json(path: str, data) -> None:
|
||||
@@ -4778,22 +4799,37 @@ def _build_pose_index_task():
|
||||
with _pose_index_lock:
|
||||
idx = _load_pose_index()
|
||||
persons = database.list_persons()
|
||||
todo = [p[0] for p in persons
|
||||
if p[0] not in idx
|
||||
|
||||
# p[17] is pose_description, p[18] is pose_skeleton
|
||||
todo = [p for p in persons
|
||||
if (p[0] not in idx or p[17] is None or p[18] is None)
|
||||
and (p[12] or "image") != "video"
|
||||
and p[0].lower().endswith(('.png', '.jpg', '.jpeg', '.webp'))]
|
||||
|
||||
_pose_index_status.update(running=True, done=0, total=len(todo))
|
||||
print(f"[pose] index build: {len(todo)} images to process")
|
||||
print(f"[pose] index build/backfill: {len(todo)} images to process")
|
||||
dirty = 0
|
||||
for fn in todo:
|
||||
for p in todo:
|
||||
fn = p[0]
|
||||
try:
|
||||
fpath = os.path.join(output_dir, fn)
|
||||
if os.path.exists(fpath):
|
||||
best = _best_person(infer(Image.open(fpath).convert("RGB")))
|
||||
desc = _pose_descriptor(best) if best is not None else None
|
||||
if desc is not None:
|
||||
idx[fn] = desc
|
||||
dirty += 1
|
||||
people = infer(Image.open(fpath).convert("RGB"))
|
||||
best = _best_person(people)
|
||||
|
||||
pose_desc = None
|
||||
pose_skel = None
|
||||
if best is not None:
|
||||
pose_desc = _describe_pose(best)
|
||||
pose_skel = json.dumps(best)
|
||||
desc = _pose_descriptor(best)
|
||||
if desc is not None:
|
||||
idx[fn] = desc
|
||||
dirty += 1
|
||||
|
||||
# Update DB if missing
|
||||
if p[17] is None or p[18] is None:
|
||||
database.upsert_person(fn, pose_description=pose_desc, pose_skeleton=pose_skel)
|
||||
except Exception as e:
|
||||
print(f"[pose] index error for {fn}: {e}")
|
||||
_pose_index_status["done"] += 1
|
||||
|
||||
Reference in New Issue
Block a user