Download adam/image_preferences.py from SyntheticMDProductions/AI_Development_Automation_Manager: direct link, hf CLI and curl.
- Browser
- Download file 11.9 kB
-
https://huggingface.co/SyntheticMDProductions/AI_Development_Automation_Manager/resolve/main/adam/image_preferences.py
- Command line
-
hf download hf://SyntheticMDProductions/AI_Development_Automation_Manager/adam/image_preferences.py
-
curl -L -o image_preferences.py https://huggingface.co/SyntheticMDProductions/AI_Development_Automation_Manager/resolve/main/adam/image_preferences.py
11.9 kB
| from __future__ import annotations | |
| from dataclasses import asdict, dataclass, field | |
| from datetime import datetime, timezone | |
| import hashlib | |
| import json | |
| from pathlib import Path | |
| from typing import Any, Callable, Sequence | |
| from adam.eve import EveVisionModel, classify_eve_embeddings | |
| RATINGS = {"favorite", "keep", "unsure", "reject"} | |
| POSITIVE_RATINGS = {"favorite", "keep"} | |
| NEGATIVE_RATINGS = {"reject"} | |
| def _now() -> str: | |
| return datetime.now(timezone.utc).isoformat() | |
| def preference_profile_id(provider_id: str, model_path: str) -> str: | |
| key = f"{provider_id}\n{str(Path(model_path).expanduser().resolve())}" | |
| return hashlib.sha1(key.encode("utf-8")).hexdigest()[:16] | |
| def image_cache_id(path: str | Path) -> str: | |
| resolved = str(Path(path).expanduser().resolve()) | |
| return hashlib.sha1(resolved.encode("utf-8")).hexdigest() | |
| class GenerationRating: | |
| image_path: str | |
| rating: str | |
| provider_id: str | |
| model_name: str | |
| model_path: str | |
| seed: int = 0 | |
| sampler: str = "" | |
| steps: int = 0 | |
| resolution: str = "" | |
| generation_settings: dict[str, Any] = field(default_factory=dict) | |
| generation_created_at: str = "" | |
| rated_at: str = field(default_factory=_now) | |
| embedding: list[float] | None = None | |
| def from_dict(cls, payload: dict[str, Any]) -> "GenerationRating": | |
| rating = str(payload.get("rating", "unsure")).casefold() | |
| return cls( | |
| image_path=str(Path(str(payload.get("image_path", ""))).expanduser().resolve()), | |
| rating=rating if rating in RATINGS else "unsure", | |
| provider_id=str(payload.get("provider_id", "")), | |
| model_name=str(payload.get("model_name", "")), | |
| model_path=str(payload.get("model_path", "")), | |
| seed=int(payload.get("seed", 0) or 0), | |
| sampler=str(payload.get("sampler", "")), | |
| steps=int(payload.get("steps", 0) or 0), | |
| resolution=str(payload.get("resolution", "")), | |
| generation_settings=dict(payload.get("generation_settings") or {}), | |
| generation_created_at=str(payload.get("generation_created_at", "")), | |
| rated_at=str(payload.get("rated_at") or _now()), | |
| embedding=[float(value) for value in payload["embedding"]] | |
| if isinstance(payload.get("embedding"), list) | |
| else None, | |
| ) | |
| class PreferenceScore: | |
| image_path: str | |
| score: float | None | |
| confidence: float | |
| category: str | |
| reason: str = "" | |
| class PreferenceProfile: | |
| def __init__(self, root: Path, provider_id: str, model_name: str, model_path: str) -> None: | |
| self.root = root.resolve() | |
| self.provider_id = provider_id | |
| self.model_name = model_name | |
| self.model_path = str(Path(model_path).expanduser().resolve()) if model_path else "" | |
| self.id = preference_profile_id(provider_id, self.model_path) | |
| self.path = self.root / "data" / "generation_preferences" / f"{self.id}.json" | |
| self.keep_threshold = 0.70 | |
| self.reject_threshold = 0.35 | |
| self.ratings: dict[str, GenerationRating] = {} | |
| self.load() | |
| def load(self) -> None: | |
| try: | |
| payload = json.loads(self.path.read_text(encoding="utf-8")) | |
| except (OSError, ValueError, TypeError, json.JSONDecodeError): | |
| return | |
| self.model_name = str(payload.get("model_name") or self.model_name) | |
| self.provider_id = str(payload.get("provider_id") or self.provider_id) | |
| self.model_path = str(payload.get("model_path") or self.model_path) | |
| thresholds = payload.get("thresholds", {}) | |
| if isinstance(thresholds, dict): | |
| self.keep_threshold = float(thresholds.get("keep", self.keep_threshold)) | |
| self.reject_threshold = float(thresholds.get("reject", self.reject_threshold)) | |
| ratings = payload.get("ratings", []) | |
| if isinstance(ratings, list): | |
| for item in ratings: | |
| if isinstance(item, dict): | |
| rating = GenerationRating.from_dict(item) | |
| self.ratings[rating.image_path] = rating | |
| def save(self) -> None: | |
| self.path.parent.mkdir(parents=True, exist_ok=True) | |
| temporary = self.path.with_suffix(".tmp") | |
| temporary.write_text( | |
| json.dumps( | |
| { | |
| "version": 1, | |
| "profile_id": self.id, | |
| "provider_id": self.provider_id, | |
| "model_name": self.model_name, | |
| "model_path": self.model_path, | |
| "thresholds": { | |
| "keep": self.keep_threshold, | |
| "reject": self.reject_threshold, | |
| }, | |
| "ratings": [asdict(item) for item in self.ratings.values()], | |
| "updated_at": _now(), | |
| }, | |
| indent=2, | |
| ), | |
| encoding="utf-8", | |
| ) | |
| temporary.replace(self.path) | |
| def set_rating( | |
| self, | |
| image_path: str | Path, | |
| rating: str, | |
| *, | |
| seed: int = 0, | |
| sampler: str = "", | |
| steps: int = 0, | |
| resolution: str = "", | |
| generation_settings: dict[str, Any] | None = None, | |
| generation_created_at: str = "", | |
| embedding: Sequence[float] | None = None, | |
| ) -> GenerationRating: | |
| clean = rating.casefold().strip() | |
| if clean not in RATINGS: | |
| raise ValueError("Generation rating must be Favorite, Keep, Unsure, or Reject.") | |
| resolved = str(Path(image_path).expanduser().resolve()) | |
| existing = self.ratings.get(resolved) | |
| record = GenerationRating( | |
| image_path=resolved, | |
| rating=clean, | |
| provider_id=self.provider_id, | |
| model_name=self.model_name, | |
| model_path=self.model_path, | |
| seed=int(seed), | |
| sampler=sampler, | |
| steps=int(steps), | |
| resolution=resolution, | |
| generation_settings=dict(generation_settings or {}), | |
| generation_created_at=generation_created_at, | |
| rated_at=_now(), | |
| embedding=[float(value) for value in embedding] if embedding is not None else ( | |
| existing.embedding if existing else None | |
| ), | |
| ) | |
| self.ratings[resolved] = record | |
| self.save() | |
| return record | |
| def rating_for(self, image_path: str | Path) -> GenerationRating | None: | |
| return self.ratings.get(str(Path(image_path).expanduser().resolve())) | |
| def examples(self) -> tuple[list[GenerationRating], list[GenerationRating]]: | |
| positive = [ | |
| item for item in self.ratings.values() | |
| if item.rating in POSITIVE_RATINGS and Path(item.image_path).is_file() | |
| ] | |
| negative = [ | |
| item for item in self.ratings.values() | |
| if item.rating in NEGATIVE_RATINGS and Path(item.image_path).is_file() | |
| ] | |
| return positive, negative | |
| def has_signal(self) -> bool: | |
| positive, _negative = self.examples() | |
| return bool(positive) | |
| class ImageEmbeddingCache: | |
| def __init__(self, root: Path, model_id: str) -> None: | |
| self.root = root.resolve() | |
| self.model_id = model_id | |
| self.folder = self.root / "data" / "image_embeddings" / hashlib.sha1(model_id.encode("utf-8")).hexdigest()[:12] | |
| def get(self, path: str | Path) -> list[float] | None: | |
| cache_path = self.folder / f"{image_cache_id(path)}.json" | |
| try: | |
| payload = json.loads(cache_path.read_text(encoding="utf-8")) | |
| except (OSError, ValueError, TypeError, json.JSONDecodeError): | |
| return None | |
| source = Path(path).expanduser().resolve() | |
| try: | |
| stat = source.stat() | |
| except OSError: | |
| return None | |
| if payload.get("path") != str(source) or payload.get("mtime") != stat.st_mtime: | |
| return None | |
| vector = payload.get("embedding") | |
| return [float(value) for value in vector] if isinstance(vector, list) else None | |
| def set(self, path: str | Path, embedding: Sequence[float]) -> None: | |
| source = Path(path).expanduser().resolve() | |
| try: | |
| stat = source.stat() | |
| except OSError: | |
| return | |
| self.folder.mkdir(parents=True, exist_ok=True) | |
| cache_path = self.folder / f"{image_cache_id(source)}.json" | |
| temporary = cache_path.with_suffix(".tmp") | |
| temporary.write_text( | |
| json.dumps( | |
| { | |
| "path": str(source), | |
| "mtime": stat.st_mtime, | |
| "model_id": self.model_id, | |
| "embedding": [float(value) for value in embedding], | |
| } | |
| ), | |
| encoding="utf-8", | |
| ) | |
| temporary.replace(cache_path) | |
| class GenerationPreferenceEvaluator: | |
| """Shared EVE-backed scorer for generated images.""" | |
| def __init__( | |
| self, | |
| root: Path, | |
| vision: EveVisionModel | None = None, | |
| *, | |
| embedder: Callable[[Sequence[str | Path]], list[list[float]]] | None = None, | |
| ) -> None: | |
| self.root = root.resolve() | |
| self.vision = vision or EveVisionModel(prefer_gpu=False) | |
| self.embedder = embedder | |
| self.cache = ImageEmbeddingCache(self.root, self.vision.model_id) | |
| def _embedding(self, path: str | Path) -> list[float]: | |
| cached = self.cache.get(path) | |
| if cached is not None: | |
| return cached | |
| vectors = self.embedder([path]) if self.embedder else self.vision.embed([path]) | |
| vector = [float(value) for value in vectors[0]] | |
| self.cache.set(path, vector) | |
| return vector | |
| def score( | |
| self, | |
| profile: PreferenceProfile, | |
| image_paths: Sequence[str | Path], | |
| *, | |
| keep_threshold: float | None = None, | |
| reject_threshold: float | None = None, | |
| ) -> list[PreferenceScore]: | |
| positive, negative = profile.examples() | |
| if not positive: | |
| return [ | |
| PreferenceScore(str(Path(path).expanduser().resolve()), None, 0.0, "Needs Review", "No preference examples yet") | |
| for path in image_paths | |
| ] | |
| positive_vectors = [item.embedding or self._embedding(item.image_path) for item in positive] | |
| negative_vectors = [item.embedding or self._embedding(item.image_path) for item in negative] | |
| image_vectors = [self._embedding(path) for path in image_paths] | |
| keep = max(0.001, min(1.0, float(keep_threshold if keep_threshold is not None else profile.keep_threshold))) | |
| reject = max(0.0, min(float(reject_threshold if reject_threshold is not None else profile.reject_threshold), keep - 0.001)) | |
| results = classify_eve_embeddings( | |
| image_paths, | |
| image_vectors, | |
| positive_vectors, | |
| negative_vectors, | |
| keep_threshold=keep, | |
| reject_threshold=reject, | |
| ) | |
| categories = {"keep": "Strong Keep", "reject": "Likely Reject", "unreviewed": "Needs Review"} | |
| return [ | |
| PreferenceScore(result.path, result.match_score, result.decision_confidence, categories[result.suggestion]) | |
| for result in results | |
| ] | |
| def score_generated_images( | |
| root: Path, | |
| *, | |
| provider_id: str, | |
| model_name: str, | |
| model_path: str, | |
| image_paths: Sequence[str | Path], | |
| keep_threshold: float | None = None, | |
| reject_threshold: float | None = None, | |
| ) -> list[PreferenceScore]: | |
| profile = PreferenceProfile(root, provider_id, model_name, model_path) | |
| evaluator = GenerationPreferenceEvaluator(root) | |
| return evaluator.score( | |
| profile, | |
| image_paths, | |
| keep_threshold=keep_threshold, | |
| reject_threshold=reject_threshold, | |
| ) | |