ASM_PNS_C/Specyfikacja-procesu-AI.md
majkarol cd292e3198 Inicjalizacja repozytorium: koncepcja platformy AdReactions + specyfikacja AI
Zawartość:
- Koncepcja 0.1 oraz rozszerzona Koncepcja 0.2 (model domenowy, architektura,
  mapowanie cel→metryki→usługi AI, wymienialność modeli, model danych)
- Katalog 15 celów analiz kognitywnych
- Specyfikacja procesu AI + opis procesów źródłowych
- Pytania do koncepcji
- Materiały źródłowe: info.md, n8n.json

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:03:32 +02:00

16 KiB
Raw Permalink Blame History

Specyfikacja procesu: analiza uwagi wzrokowej kreacji reklamowych

Opis logiki procesu niezależny od narzędzia orkiestrującego, przeznaczony do implementacji jako komponent oprogramowania (np. usługa backendowa / pipeline). Definiuje: dane wejściowe, kontrakty zewnętrznych usług AI, kolejność i równoległość wywołań, model danych wynikowych oraz logikę prezentacji.


1. Cel i zakres

System przyjmuje pojedynczy obraz (kreację reklamową / grafikę) i zwraca zestaw analiz:

  1. Rozumienie zawartości — jakie obiekty są na obrazie i gdzie się znajdują.
  2. Predykcja uwagi wzrokowej (saliency) — gdzie skupi się wzrok odbiorcy; trzy niezależne modele dla walidacji krzyżowej.

Wynikiem są dane (lista obiektów z ramkami, mapy uwagi) oraz pochodne wizualizacje. Proces jest bezstanowy — jedno wejście (obraz) → jeden komplet wyników.


2. Architektura logiczna

        ┌────────────────────┐
        │  Wejście: obraz    │
        └─────────┬──────────┘
                  ▼
        ┌────────────────────┐
        │  Preprocessing     │  bytes + base64 + mime + (w,h)
        └─────────┬──────────┘
                  │
   ┌──────────────┼───────────────┬───────────────┬───────────────┐
   ▼ (łańcuch A)                  ▼ (B)           ▼ (C)           ▼ (D)
┌──────────┐                  ┌──────────┐   ┌──────────┐   ┌──────────┐
│ LLaVA    │                  │ DeepGaze │   │ UNISAL   │   │ ASM      │
│ (etykiety)│                 │(saliency)│   │(saliency)│   │(2× saliency)
└────┬─────┘                  └────┬─────┘   └────┬─────┘   └────┬─────┘
     ▼                             │              │              │
┌──────────────┐                   │              │              │
│ Grounding    │                   │              │              │
│ DINO (boxy)  │                   │              │              │
└────┬─────────┘                   │              │              │
     │                             ▼              ▼              ▼
     ▼                       ┌──────────────────────────────────────┐
┌──────────────┐             │  Agregacja wyników saliency          │
│ Wynik:       │             └──────────────────┬───────────────────┘
│ detekcja     │                                ▼
└──────────────┘                    ┌──────────────────────────┐
                                    │ Artefakty wyjściowe:     │
                                    │ • overlay boxów          │
                                    │ • nakładka heatmapy      │
                                    │ • porównanie 2×2         │
                                    └──────────────────────────┘

Kluczowe zależności:

  • Łańcuch A jest sekwencyjny: Grounding DINO potrzebuje etykiet z LLaVA.
  • Zadania B, C, D oraz cały łańcuch A są względem siebie niezależne → wykonywane równolegle.
  • Punkt agregacji czeka na zakończenie wymaganych zadań przed złożeniem danego artefaktu.

3. Dane wejściowe i preprocessing

Wejście: plik graficzny (PNG lub JPEG).

Preprocessing — z jednego uploadu przygotuj reprezentację współdzieloną przez wszystkie usługi:

ImageInput {
  bytes   : binary        // oryginalne bajty pliku (do multipart/form-data)
  base64  : string        // base64 bez prefiksu data: (do osadzania i obliczeń)
  mime    : "image/png" | "image/jpeg"
  width   : int
  height  : int
}
  • mime, width, height ustal standardową biblioteką do obrazów (np. Pillow / image-size / sharp).

    Uwaga: pierwotna implementacja parsowała nagłówki ręcznie (PNG: width@offset16, height@offset20 jako uint32 BE; JPEG: skan markerów SOF0 0xC0 / SOF2 0xC2). W docelowym kodzie użyj gotowej biblioteki — wymiary i tak są potrzebne tylko do pozycjonowania ramek i renderowania (sekcja 7).

  • base64 służy do: (a) osadzania oryginału w wizualizacjach, (b) blendu pikselowego.
  • bytes służy do wszystkich wywołań usług (pole multipart image lub file).

4. Wewnętrzny model danych (wyników)

DetectionResult {
  objects : [ { object_type: string,
                bbox_xyxy:  [x1, y1, x2, y2],   // piksele, układ XYXY
                score:      float } ]            // 0..1
  model_id?  : string
  threshold? : float
}

SaliencyMap {
  source       : "deepgaze" | "unisal" | "asm_detailed" | "asm_general"
  image_base64 : string
  mime         : string
}

AnalysisResult {
  image     : ImageInput
  detection : DetectionResult
  saliency  : SaliencyMap[]    // 4 pozycje: deepgaze, unisal, asm_detailed, asm_general
}

5. Zewnętrzne usługi AI — kontrakty API

Wszystkie usługi to HTTP POST z ciałem multipart/form-data zawierającym obraz. Adresy hostów i token pochodzą z konfiguracji / magazynu sekretów (sekcja 8). Każde wywołanie powinno mieć skończony timeout i być odporne na błędy (sekcja 9).

Kształty odpowiedzi oznaczone „(wnioskowane)" odtworzono na podstawie sposobu konsumpcji danych — przy implementacji potwierdź je z dokumentacją/realnymi odpowiedziami usług.

5.1. LLaVA — ekstrakcja typów obiektów

Multimodalny model wizualno-językowy; zwraca listę kategorii obiektów widocznych na obrazie.

POST http://{LLAVA_HOST}/llava-api/v1/get-object-types
Headers:
  accept: application/json
  Authorization: Bearer {TOKEN}
Body (multipart/form-data):
  temperature = 0.2        // niska → powtarzalność
  top_p       = 0.9
  image       = <plik>

Odpowiedź (wnioskowane):
  { "labels": ["person", "bottle", "logo", ...] }

Transformacja po stronie klienta: połącz labels w jeden ciąg rozdzielony przecinkami ("person, bottle, logo") — wejście dla Grounding DINO.

5.2. Grounding DINO — detekcja obiektów (bounding boxy)

Otwarto-zbiorowa (zero-shot) detekcja sterowana tekstem: dla podanych etykiet zwraca ramki.

POST http://{GROUNDING_DINO_HOST}/grounding-dino-api/v1/get-objects-bboxes
Headers:
  accept: application/json
  Authorization: Bearer {TOKEN}
Body (multipart/form-data):
  object_types = "{labels_z_LLaVA}"   // np. "person, bottle, logo"
  max_objects  = 50
  base64       = false
  image        = <plik>

Odpowiedź (wnioskowane):
  {
    "objects_bboxes": [
      { "object_type": "logo",
        "bbox_coords_xyxy": [x1, y1, x2, y2],
        "score": 0.87 }
    ],
    "model_id":  "...",   // opcjonalnie
    "threshold": 0.3,     // opcjonalnie
    "width":  839,        // opcjonalnie (fallback wymiarów)
    "height": 1190
  }

5.3. DeepGaze — mapa uwagi (saliency)

Predykcja rozkładu uwagi wzrokowej; zwraca heatmapę zakodowaną base64.

POST http://{DEEPGAZE_HOST}/v1/predict-heatmap
Headers:
  accept: application/json
  Authorization: Bearer {TOKEN}
Body (multipart/form-data):
  image = <plik>

Odpowiedź (wnioskowane):
  { "heatmap_b64": "<base64>",
    "heatmap_mime": "image/png",
    "width": 839, "height": 1190,
    "model": "deepgaze..." }

→ mapuj na SaliencyMap{ source:"deepgaze", image_base64:heatmap_b64, mime:heatmap_mime }.

5.4. UNISAL — mapa uwagi (saliency, model porównawczy)

POST http://{UNISAL_HOST}/unisal/process-image?as_base64=true
Headers:
  accept: application/json
  X-API-Key: {TOKEN}
Body (multipart/form-data):
  file = <plik>

Odpowiedź (wnioskowane):
  { "data": "<base64>", "mimetype": "image/jpeg" }

SaliencyMap{ source:"unisal", image_base64:data, mime:mimetype }.

5.5. ASM (asmModel) — mapy uwagi z warunkowaniem promptem

Model centralny: zwraca dwie mapy uwagi (szczegółową i ogólną), warunkowane tekstowym promptem osadzającym kontekst marketingowy.

POST http://{ASM_HOST}/asmModel/process-image
     ?prompt=Describe the image in the style of a polished marketing ad.
     &as_raw_output=false
     &max_new_tokens=100
Headers:
  accept: application/json
  X-API-Key: {TOKEN}
Body (multipart/form-data):
  file = <plik>

Odpowiedź (wnioskowane):
  { "image_detailed": "<base64>",
    "image_general":  "<base64>",
    "mimetype": "image/jpeg" }

→ dwa wpisy: SaliencyMap{source:"asm_detailed",...} oraz SaliencyMap{source:"asm_general",...}.

Uwaga: architektura ASM nie wynika z kontraktu — to wewnętrzny mikroserwis. prompt i max_new_tokens sugerują model multimodalny warunkowany językiem. Prompt potraktuj jako parametr konfigurowalny, nie stałą.


6. Orkiestracja

Logika sterująca (zastępuje przepływ narzędzia) — uruchom niezależne gałęzie równolegle, zachowując jedyną zależność LLaVA → Grounding DINO.

async def analyze(image_bytes) -> AnalysisResult:
    img = preprocess(image_bytes)          # bytes, base64, mime, w, h

    async def detection_chain():
        labels = await llava_object_types(img.bytes)      # 5.1
        labels_str = ", ".join(labels)
        return await grounding_dino(img.bytes, labels_str) # 5.2

    # gałęzie niezależne — równolegle
    detection, deepgaze, unisal, asm = await gather(
        detection_chain(),                 # łańcuch A (sekwencyjny wewnątrz)
        deepgaze_heatmap(img.bytes),       # B
        unisal_saliency(img.bytes),        # C
        asm_saliency(img.bytes, PROMPT),   # D
        return_exceptions=True,            # patrz sekcja 9
    )

    saliency = [
        SaliencyMap("deepgaze",     deepgaze.heatmap_b64, deepgaze.heatmap_mime),
        SaliencyMap("unisal",       unisal.data,          unisal.mimetype),
        SaliencyMap("asm_detailed", asm.image_detailed,   asm.mimetype),
        SaliencyMap("asm_general",  asm.image_general,    asm.mimetype),
    ]
    return AnalysisResult(img, detection, saliency)

Zasady:

  • Cztery gałęzie startują jednocześnie; całkowity czas ≈ czas najwolniejszej gałęzi.
  • Punkt agregacji łączy wyniki dopiero, gdy potrzebne gałęzie się zakończą.
  • Każdy artefakt wyjściowy zależy od konkretnego podzbioru wyników (sekcja 7) — można je generować, gdy tylko jego zależności są gotowe.

7. Warstwa prezentacji (artefakty wyjściowe)

Trzy artefakty. Można je renderować po stronie klienta (HTML/Canvas — jak w oryginale) lub serwerowo komponować obrazy (Pillow / sharp / canvas). Poniżej logika niezależna od wyboru.

7.1. Wizualizacja detekcji obiektów

Zależności: oryginał + DetectionResult.

  • Dla każdego obiektu narysuj ramkę z bbox_xyxy, podpis "{object_type} {score%}".
  • Kolor per typ obiektu (paleta cykliczna; ten sam typ = ten sam kolor).
  • Pozycje przeliczaj na procenty wymiarów obrazu (x1/width, y1/height, …), aby skalowały się responsywnie.
  • Opcjonalnie: filtry pokazujące/ukrywające typy, legenda, licznik obiektów.

7.2. Nakładka pojedynczej mapy uwagi

Zależności: oryginał + jedna SaliencyMap (np. DeepGaze).

  • Heatmapa nałożona na oryginał z regulowaną przezroczystością (suwak 0100%).

7.3. Porównanie map uwagi (siatka 2×2)

Zależności: oryginał + 4 mapy (deepgaze, unisal, asm_detailed, asm_general).

  • Cztery kafelki, wspólny suwak intensywności, technika „inwersji" (7.4).

7.4. Algorytm „inwersji" heatmapy (blend luminancji)

Wspólna logika nakładek. Dla parametru t ∈ [0,1] (intensywność / pozycja suwaka):

# Z heatmapy licz luminancję (jasność uwagi) 0..1:
lum = (0.299*R + 0.587*G + 0.114*B) / 255

# Blend per kanał (RGB), per piksel:
out = orig * (1 - t) + (lum * 255) * t
  • t = 0 → czysty oryginał; t = 1 → maska uwagi w skali szarości (biel = wysoka uwaga, czerń = niska) → efekt „reflektora".
  • Wymaga zgodności rozdzielczości oryginału i heatmapy (w razie potrzeby przeskaluj heatmapę).

8. Konfiguracja i sekrety

Wynieś poza kod (zmienne środowiskowe / vault):

Klucz Opis
LLAVA_HOST host usługi LLaVA
GROUNDING_DINO_HOST host usługi Grounding DINO
DEEPGAZE_HOST host usługi DeepGaze
UNISAL_HOST host usługi UNISAL (w oryginale 1.208.108.242:58951)
ASM_HOST host usługi ASM (w oryginale ten sam host co UNISAL)
TOKEN poświadczenie (Bearer dla LLaVA/DINO/DeepGaze; X-API-Key dla UNISAL/ASM)
ASM_PROMPT prompt warunkujący ASM (domyślnie marketingowy)
MAX_OBJECTS limit detekcji (domyślnie 50)

Dwa schematy autoryzacji: Authorization: Bearer (LLaVA, Grounding DINO, DeepGaze) vs X-API-Key (UNISAL, ASM). Zaimplementuj per usługa.


9. Obsługa błędów i odporność

W oryginale węzły LLaVA, DeepGaze, UNISAL i ASM były ustawione na kontynuację mimo błędu — awaria pojedynczego modelu nie przerywała całości. Odtwórz to:

  • Degradacja stopniowa: błąd jednej gałęzi → pomiń jej artefakt, zwróć pozostałe (return_exceptions / per-task try/except). Nie przerywaj całej analizy.
  • Twarda zależność: jeśli LLaVA zawiedzie, Grounding DINO nie ma etykiet → pomiń detekcję (lub fallback: pusta lista / domyślne etykiety), reszta map uwagi działa dalej.
  • Timeouty i retry: skończony timeout na każde wywołanie; ewentualny retry z backoffem dla błędów przejściowych (5xx / timeout).
  • Walidacja odpowiedzi: sprawdzaj obecność kluczy (labels, objects_bboxes, heatmap_b64, data, image_detailed/image_general) przed użyciem.
  • Zgodność wymiarów: przy blendzie/overlayu pilnuj zgodności rozdzielczości oryginału i map.

10. Proponowana dekompozycja modułów

Moduł Odpowiedzialność
preprocess walidacja pliku, base64, mime, wymiary
clients/ po jednym kliencie na usługę (LLaVA, GroundingDINO, DeepGaze, UNISAL, ASM); auth, timeout, parsowanie odpowiedzi
orchestrator równoległe uruchomienie gałęzi, agregacja, obsługa błędów (sekcja 6, 9)
models typy danych (sekcja 4)
render/ generowanie artefaktów (overlay boxów, nakładka heatmapy, siatka 2×2 + blend)
api/cli punkt wejścia: przyjmij obraz → zwróć AnalysisResult + artefakty

Sugerowany stack: dowolny z natywną asynchronicznością i obsługą multipart oraz obrazów — np. Python (FastAPI + httpx.AsyncClient + Pillow) lub Node (Fastify/Express + undici/fetch + sharp). Renderowanie wizualizacji: serwerowo (kompozycja obrazu) albo zwrot danych + szablon kliencki.


11. Rozszerzenia (roadmapa)

Pierwotny projekt przewidywał dalsze etapy analizy uwagi (jeszcze niezaimplementowane):

  • Mapa cieplna w interwałach czasowych (np. „30 s, 6 obrazów", „20 s → 0,5 s") — saliency rozłożona na przedziały czasu.
  • Ścieżki fiksacji (scanpath) — przewidywana sekwencja ruchów oka.
  • Mapa emocji — predykcja reakcji emocjonalnej na kreację.

Architektura z sekcji 6 jest na to przygotowana: dokładaj kolejne niezależne gałęzie do równoległej orkiestracji i nowe artefakty do warstwy prezentacji.


Specyfikacja odtworzona z istniejącego przepływu przetwarzania; kontrakty odpowiedzi oznaczone „wnioskowane" wymagają potwierdzenia z dokumentacją docelowych usług AI.