GMI × WORLD CUP 2026
← Back to App
Technical Architecture

AI Pipeline —
Team Photo
Generation

3AI models in pipeline
~15sAvg. generation time
11Max faces per photo
48World Cup 2026 nations
System Diagram
BROWSER Camera · Upload MediaPipe BlazeFace WASM Canvas collage builder HTTP FLASK :5050 Python · server.py ENDPOINTS /api/vision /api/generate /api/identity-score /api/download async queue + 2s poll · 120s budget build_edit_payload() per model family GMI CLOUD · gmi-serving.com ~3s ~15s ~5s STEP 01 · VISION · /v1/chat/completions Gemini 3.1 Flash Lite Extracts face attributes as JSON: age band, skin tone, hair, facial hair, glasses response_format: json_object · max_tokens: 200 · temp: 0.2 One call per face crop · parallel requests · 512×512 JPEG input ~3s STEP 02 · GENERATE · /apikey/requests (async queue) Gemini 3.1 Flash Image (preview) Identity-preserving edit: reference collage → FIFA team photo · 1024×1024 Submit → receive request_id → poll /requests/{id} every 2s → inline base64 → data URI 768×768 JPEG collage input · n: 1 · gpt-image-2-edit available via EDIT_MODEL ~15s STEP 03 · SCORE · /v1/chat/completions GPT-4o Vision Reference vs generated: face-to-face comparison · returns 0–100 fidelity score verdict: same | similar | different · one-sentence notes · temp: 0.1 Used in bench tool · overridable via IDENTITY_MODEL env var ~5s
Endpoint Reference & Design Decisions
Endpoint Model Route Latency
POST /api/vision gemini-3.1-flash-lite GMI Chat API
json_object mode
~3s
POST /api/generate gemini-3.1-flash-image-preview GMI Queue API
submit + poll
~15s
POST /api/identity-score openai/gpt-4o GMI Chat API
json_object mode
~5s
GET /api/download Proxies GCS URLs — avoids CORS on storage.googleapis.com. Validates origin domain before fetching.
Gemini Flash Lite for vision, not GPT-4o
40% faster on the same structured JSON attribute prompt (~3s vs ~5s). response_format: json_object is reliable on both; Gemini wins on throughput per face crop when running N calls in parallel.
Gemini Flash Image (preview) for generation, not GPT-Image-2-Edit
Bench across both: Gemini averaged 14.6s per generation with a consistent 85/100 identity score; GPT-Image-2-Edit averaged 124s with variable 50–92 identity and frequent 60s+ outliers. Gemini wins on both throughput and identity stability. EDIT_MODEL env var swaps back to gpt-image-2-edit when max-fidelity matters more than speed.
Client-side face detection (MediaPipe WASM)
BlazeFace runs entirely in the browser — zero server round-trip for detection. Each crop is normalized to 512×512 and sent individually to /api/vision, keeping server payloads small and calls parallelizable.
768×768 JPEG collage, not raw photo
All face crops are assembled into a labeled grid before sending to the image model. This normalizes face scale regardless of source position, and JPEG at 0.88 quality is ~50% smaller than PNG with no visible degradation at 1024px output resolution.
Key Payload Shapes
POST /api/vision
Vision Request
{
  "model": "gemini-3.1-flash-lite",
  "messages": [{
    "role": "user",
    "content": [
      { "type": "text",
        "text": "<VISION_PROMPT>" },
      { "type": "image_url",
        "image_url": {
          "url": "data:image/jpeg;base64,…"
        }}
    ]
  }],
  "response_format": {
    "type": "json_object" },
  "max_tokens": 200,
  "temperature": 0.2
}
POST /api/generate → GMI Queue
Generate Request
{
  "model": "gemini-3.1-flash-image-preview",
  "payload": {
    "prompt": "OFFICIAL FIFA PRE-MATCH…",
    "image": "data:image/jpeg;base64,…",
    "size": "1024x1024",
    "n": 1
  }
}

// Poll response (success — Gemini)
{
  "status": "completed",
  "outcome": {
    "candidates": [{
      "content": { "parts": [{
        "inlineData": {
          "mimeType": "image/png",
          "data": "<base64>"
        }
      }] }
    }]
  }
}
Vision model response
Attributes JSON
{
  "apparent_age_band": "30s",
  "apparent_gender_presentation":
    "masculine",
  "hair": "short black",
  "facial_hair": "stubble",
  "glasses": false,
  "skin_tone": "medium",
  "distinguishing": "prominent brow"
}

// Used to build the per-player
// guide section of the image
// generation prompt