Spaces:
Runtime error
Runtime error
Commit History
-
Log full source image instead of cropped face
detect_and_crop_source now returns a 1024px-capped version of the original input alongside the cropped face. The JS stores this server-resized original in originalSourceImages and syncs it to Gradio immediately after processing, so swap_faces reliably receives the full image for logging in the source_images column. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d0cfa98
-
Scale GPU duration dynamically by face count
50 + n*20s gives 70s/90s/110s/130s for 1-4 faces, covering p95 for all observed cases based on log analysis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ff6545d -
Reduce GPU duration from 120s to 90s based on log analysis
p95 of actual duration_seconds is 80s across 194 requests; 90s covers 97.9%. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4a6a548
-
Fix intermittent missing detection results by adding a nonce to responses
Gradio's change event is skipped when the output value is unchanged, which caused both target and source face detection results to silently not appear whenever the same image was re-uploaded. Adding a unique nonce to every JSON response ensures the value always differs and the change event fires. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5088955 -
Simplify expand_bbox_for_head: remove top_padding_fraction and default
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>691fee6 -
Expand source face crop by 20% margin to include hair and context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>d5db609 -
Simplify smoothing pass to take only the result image
The seam is visible in the composited result alone, so the original target image is not needed as context. Drop target_resized from the smoothing call and update the prompt accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>0fb86e7 -
Move Flux smoothing to a single pass over the full result image
Instead of smoothing each face crop individually inside the loop, run one harmonization inference on the fully composited result after all swaps are pasted, so all seams are blended together in one pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>7fe6a68 -
Add Flux smoothing pass after face swap to reduce seam artifacts
Runs a second Flux2KleinPipeline inference at 2 steps with a harmonization prompt after the swap pass, blending the composited head's edges into the target background before pasting back. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9c8dc91 -
Resize source thumb container to match face crop aspect ratio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e69f4f9 -
Crop source face to tight bbox instead of expanded head region
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>5e9c3a3 -
Show full source face in thumbnail using object-fit contain
Prevents portrait-oriented head crops from being clipped at the top/bottom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f2ed620 -
Fix drag-and-drop disabled on no-face source slot
The no-face box was missing dragover/dragleave/drop listeners, so users could not drag a replacement image onto it. Also adds amber drag-over highlight to match the normal empty slot behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>e574102 -
Auto-detect and crop source face on upload
When a user uploads a source image, the server now runs InsightFace on it (CPU), crops to the head region via expand_bbox_for_head, and returns the cropped image. The slot shows a spinner while processing and a red warning if no face is found, keeping the swap button disabled until every source is valid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>6c691e6 -
Remove gr.update() from _swap_faces_gpu — yield None for intermediate steps, translate at Gradio boundary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>480c55a -
Remove dead global cache for flux pipeline — ZeroGPU forks per call so globals never persist
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f069788 -
Add logging to investigate _flux_pipe cache behavior across ZeroGPU calls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ed62b20 -
Add pre-commit black formatter and apply initial formatting
Adds .pre-commit-config.yaml pinned to black 24.10.0 and [tool.black] config (line-length=88, target-version=py310) in pyproject.toml. Adds pre-commit to dev dependencies. Runs black --all-files to bring the existing codebase into conformance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>db79f31 -
Expand all abbreviated variable and function names
No logic changes. Renames throughout image_utils, pipeline, pipeline_flux, and app: crop_r→crop_resized, src_r→source_resized, img_w/h→image_width/height, fw/fh→face_width/height, pad_frac→padding_fraction, x1e/y1e→expanded_left/top, pil_img→image, cv2_img→bgr_image, thumb→thumbnail, buf→buffer, _collect_source_pils→_collect_source_images, and related dict keys. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>bc09ad0 -
Move face crop/resize preprocessing out of GPU scope
Splits run_swap_flux into prepare_swap_crops (CPU: base64 decode, crop, resize) and run_swap_flux (GPU: pipe inference + paste only). prepare_swap_crops is called in swap_faces before _swap_faces_gpu, so GPU time is spent exclusively on Flux2 inference. Also removes unused _pil_to_cv2 import. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f0ab832 -
Fix face index mismatch between detection and swap phases
Detection now uses buffalo_l (upgraded from buffalo_sc) so detection-phase bboxes are authoritative. Bboxes are forwarded from the UI through a new bboxes-json channel and used directly in run_swap_flux, eliminating the re-detection step that caused wrong faces to be swapped when the two models produced different face orderings. Also removes _make_face_analyzer and the wasted CPU inference inside the @spaces.GPU scope. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f0c2d43
-
Move logging outside @spaces.GPU scope to avoid wasted GPU time
Splits swap_faces into _swap_faces_gpu (GPU inference only) and a swap_faces wrapper that validates inputs before acquiring the GPU, then calls spawn_log in a finally block after the GPU generator is exhausted — ensuring the logging thread is never spawned inside the ZeroGPU scope. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>16a9469 -
Fix Swap Faces and Download buttons to match dark amber theme
Browser UA stylesheet was overriding custom CSS on disabled/button elements. Added appearance:none resets and !important guards so the themed amber styles render correctly instead of browser-default gray. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4e9d506 -
Increase buffalo_sc det_size back to 640x640 for better detection accuracy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>06e0622 -
Switch CPU face detector to buffalo_sc at 320x320 for faster detection
buffalo_sc (SCRFD-500MF) is ~10-20x fewer FLOPs than buffalo_l (SCRFD-10GF), and halving det_size cuts inference ~4x further — detection-only step, so landmark accuracy trade-off is acceptable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>30536d2 -
Add BFL usage policy notice and model license section
Links to bfl.ai/legal/usage-policy in both the notice bar and the privacy policy collapsible; updates last-modified date to 2026-05-20. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3ee50c3 -
Label face detection status as CPU only
Clarifies that detection does not consume ZeroGPU quota. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>338aaa9 -
Remove InsightFace swapper and GFPGAN; use Flux2 as the only swap mode
Drops inswapper_128.onnx, GFPGAN, and the fast-mode pipeline entirely. InsightFace FaceAnalysis is kept for face detection and bbox cropping. Face limit raised from 2 to 8, mode toggle removed from the UI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1311044 -
Move Flux2 download to startup (CPU) to avoid burning GPU time
from_pretrained + load_lora_weights now run at module level on CPU — no GPU seconds consumed. Inside @spaces.GPU, only pipe.to("cuda") runs (fast memory transfer). GPU duration reduced from 300s to 120s. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>a60dc1f -
Pass HF_TOKEN to Flux2 pipeline loader for gated model access
black-forest-labs/FLUX.2-klein-9B is a gated repo; without a token the download returns 403. Read HF_TOKEN from env (same pattern as the inswapper download) and pass it to from_pretrained and load_lora_weights. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3b21cc0 -
Add Flux2 Quality mode for selective face swap
Introduces FLUX.2 Klein 9B + BFS-Best-Face-Swap LoRA as an optional Quality backend alongside the existing Fast (InsightFace/inswapper) mode. For each selected face, crops the expanded head region from the target, runs the Flux2 pipeline with the source face, and composites the result back — making Flux2 multi-face-aware for the first time. - pipeline_flux.py: bbox expansion, resize-for-flux, lazy pipeline loader, and run_swap_flux (crop → Flux2 → paste per selected face) - app.py: swap_faces_quality() with @spaces.GPU(duration=300), lazy _flux_pipe global, new hidden #run-quality-btn wired to Gradio - templates/app.html: ⚡ Fast / ✨ Quality toggle in Run panel - wire_outputs.js: swapMode state, updateMode(), Quality guard (max 2 faces), clickGradioRunBtn() routes to correct hidden button - app.css: mode toggle styles, .app-badge.flux, quality-warning - requirements.txt / pyproject.toml: add diffusers (git), peft, transformers, accelerate; pin onnxruntime<1.21 for local dev C…81fb298
-
Position upload text independently above SVG icon in drop zone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>b997b37 -
Revert upload prompt position; shrink SVG icon to fit drop zone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>de1ba41 -
Shift upload prompt slightly upward in drop zone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>f9d13c4 -
Replace hardcoded blue SVG colors in upload icon with amber
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4ab7edd -
Switch theme from purple to amber/orange palette for better visibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1963c43 -
Fix double bullet: suppress Gradio's prose ul list-style on notice list
Gradio's .prose ul { list-style: circle inside } was adding a circle marker alongside our ::before dot. Scoping to .app-notice and adding !important beats the Gradio rule. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1cc0618 -
Darken background layers while keeping borders and accents
Pull page bg (#1a0a38→#0d0520), app shell (#2d1060→#180840), and all content-area fills back toward darker without touching borders, text, or accent colours. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>408abe9 -
Refresh theme to medium-dark purple palette
Replace near-black backgrounds (#0d0010/#1a0024) with richer purples (#1a0a38/#2d1060), visible borders (#7c3aed), brighter accents (#c084fc/#7c3aed), and lighter text (#faf5ff/#ddd6fe/#c4b5fd). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>709360f -
Fix all text colors by overriding Gradio CSS variable at app-shell
Gradio's typography.css applies '.prose * { color: var(--body-text-color) }' to all descendants, and --body-text-color defaults to #27272a (neutral_800). Setting --body-text-color:#e4e4e7 on .app-shell overrides the variable for our entire UI without needing !important on individual elements. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3bad4da -
Move js to launch(); use !important to override Gradio text colors
In Gradio 6 the js param moved from Blocks() to launch(). Also add !important to all text colors overridden by Gradio's injected styles since the .gradio-container prefix approach had no effect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>3dd1a64 -
Fix text colors by raising specificity with .gradio-container prefix
Gradio's own injected CSS wins over plain class selectors. Prefixing affected rules with .gradio-container beats Gradio's specificity without needing !important overrides. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>4288102 -
Force Gradio dark mode; remove workaround !important overrides
Adding 'dark' class to <html> at init makes Gradio use its own light text palette instead of #27272a, so per-element !important hacks on .hint-text, .consent-label, and strong tags are no longer needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>81a5429 -
Fix consent label text wrapping broken by flexbox
The label uses display:flex which turned the text node, <a>, and closing paren into separate flex items. Wrapping in a <span> keeps them as inline content inside a single flex item. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>57a346b -
Fix strong tag color overridden by Gradio stylesheet
Gradio applies color:#27272a to strong elements globally; reset all strong tags in the app shell to inherit, then explicitly set the notice strong color to match surrounding text. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>449d949 -
Force consent and hint text colors over Gradio overrides
Gradio injects its own color (#27272a) that was winning over our .consent-label and .hint-text rules; adding !important fixes it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>727ce14 -
Improve text readability on dark theme
Brighten secondary and placeholder text colors that were nearly invisible against the dark purple backgrounds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9da214c -
Add consent checkbox gating the Swap Faces button
A checkbox labelled with a link to the Privacy Policy must be checked before the run button enables. The check resets on every page load (no localStorage) so consent is explicit for each session. updateRunButton() now requires consent in addition to face selection and source images being ready. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>160bddb -
Add GDPR-compliant logging disclosure and Privacy Policy
Adds a notice bullet informing users that uploaded images and results are logged to a private dataset and auto-deleted after 7 days, plus an expandable Privacy Policy covering what is collected, legal basis (GDPR Art. 6(1)(f)), storage, retention, data subject rights, and complaint routes. Pattern adapted from FireRed-Experimental-Turbo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>81b7a29 -
Fix blank screen: pin gradio==6.14.0 and remove ssr_mode=False
Unpinned gradio in requirements.txt allowed pip to install a version different from sdk_version 6.14.0 in README.md. The running app then generated asset hashes that didn't match what the HF Space proxy served, causing 404s for the bundled JS/CSS and a blank screen. ssr_mode=False was also removed — it interferes with static-file route registration in Gradio 5+/6+ and isn't needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>911d50e