Fix mask-selection bugs; add Makefile convenience runner - #2
Merged
Merged
Conversation
…dead code Agent 1 (occlusion_agent): auto-detects subject + occluder, fuses InstaFormer holistic occlusion/depth prediction with SAM3 (point- and text-prompt) segmentation. Agent 2 (_run_flux_fill_inpaint): FLUX.1-Fill-dev inpaints the hidden region, now with an explicit prompt/negative-prompt instruction not to regenerate the occluder itself. Agent 3 (new reviewer/retry loop in test_flux_cutout_person.py): GPT-vision scores each completion against the original photo and retries with a corrected prompt on a low score, reusing the previously-orphaned REVIEWER_SCHEMA. Also: tuned GPU_MEMORY_LIMIT_GB/FLUX_FILL_STEPS for a 48GB RTX A6000 instead of the original 12GB-card defaults, removed sequential CPU offload entirely, and deleted dead legacy code with zero live callers (pix2gestalt, AISFormer inference, LaMa, CLIP grounding, GroundingDINO, PSALM, the old inpainting_agent/reviewer/route/build_graph LangGraph tail, mixed_context.py, instaorder_helper.py) — main.py 5680->2952 lines, config.py 341->217 lines, verified via py_compile + module import + live end-to-end test runs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…d test runner - README.md, run_batch.sh, run_batch_20.sh: fix stale references to main.py/config.py/test_flux_cutout_person.py left over from the pre-restructure layout; document the live Agent 3 reviewer and InstaFormer setup. - run_batch.sh/run_batch_20.sh: pass the per-image prompt hint as a pipeline.py CLI arg instead of sed-patching src/config.py on disk between runs. - src/pipeline.py: accept an optional second CLI arg to override config.INPUT_PROMPT for a single run. - Remove the ControlNet+SD-1.5 inpaint fallback (src/models/controlnet.py, INPAINT_BACKEND/CONTROLNET_*/SD_INPAINT_*/SHAPE_PRIOR_THRESH config) — FLUX.1-Fill-dev is the only backend and always will be, so the fallback path was dead weight. - Fix a stale config.py comment claiming the Agent 3 reviewer was removed; it's live (USE_REVIEWER=True) as the inline retry loop in pipeline.py. - Add test_pipeline.py: one CLI entry point that runs the pipeline against either a single image or every image in a directory, replacing the now-removed root-level test_flux_cutout_person.py. - Remove stale __pycache__ bytecode for modules deleted/moved in the restructure (main.py, test_flux_cutout_person.py, config.py, instaorder_helper.py, mixed_context.py). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e runs + audit Found through iterative test runs on bunny/horse and a follow-up codebase audit for the same bug class (config flags not actually respected, data silently dropped between code paths, GPU models reloaded needlessly): - Guard against and auto-correct an inverted visible_mask.png (stale cache had foreground/background swapped), and persist the correction to disk so the cache actually sticks instead of re-triggering Agent 1 forever. - Retry loop now keeps the best-scoring attempt across all retries, not just whichever ran last. - Bound the Flux inpaint region to a subject-sized area instead of the entire dilated occluder (was painting into a whole snowbank-sized hole for a small partially-visible subject). - Rewrite the default Flux prompt to explicitly state single-subject, region-only, no-background-regeneration constraints instead of vaguer wording that let Flux paint duplicate subjects / replace backgrounds. - Lower FLUX_FILL_GUIDANCE_SCALE 45->30 (BFL's own documented default for FLUX.1-Fill-dev specifically). - Split the CLIP/T5 prompt path (FluxFillPipeline) so CLIP's 77-token cap no longer silently truncates the merged prompt+"Avoid:" clause; T5's max_sequence_length is now sized dynamically per-call instead of a fixed 512, so short prompts skip paying for padding-token attention. - Keep Flux-Fill resident across retry attempts instead of reloading the 12B-param model from scratch on every attempt. - occluder_text (the "don't draw the occluder here" prompt clause) was silently reset to "" whenever cached masks were reused instead of being read back from the saved occlusion.json. - occlusion_agent.py's off-frame-extension trigger never actually checked config.USE_OFFFRAME_EXTENSION, so a "disabled" off-frame pass still ran a full extra Flux outpaint whenever GPT flagged an image frame-cropped. - Fix a missing `import traceback` that turned Agent 1's own soft-fail exception handler into a hard crash. - Wire config.GPT_MAX_TOKENS into the actual Responses API call (it was defined and referenced in an error message but never passed to the API), and raise it 10192->32000 for reasoning-heavy calls. - Align getattr() fallback defaults for kill-switch flags (USE_OFFFRAME_EXTENSION/USE_AMODAL_COMPLETION/FLUX_FILL_CPU_OFFLOAD/ USE_INSTAFORMER) with their actual config.py values, so a future accidental removal fails safe instead of silently inverting behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ing, click-point non-determinism, oversized-occluder sanity check - Add sam3_text_occluder to MASK_FUSION_PRIORITY (was silently losing to InstaFormer even when badly oversized) - Replace GPT click-point InstaFormer matching with deterministic SAM3-text segmentation + position-word disambiguation (USE_OCCLUDER_CLICK=False by default, old behavior still available via the flag) - Add area-ratio sanity check that trims oversized occluder masks before the hidden-region dilate step - Fix stale INPUT_PROMPT="horse" default that silently hinted every no-hint run - Rename output folder after Agent 1's real subject instead of the pre-detection placeholder - Restrict subject selection away from humans for now (fully-occluded hand/finger anatomy is an unsolved Flux weak point) - Add flux_depth.py (two-stage depth-guided fill experiment, gated off by default — evidence showed it underperforms plain Flux-Fill on hard cases) - Document all of the above plus the LISA evaluation (not integrated) in README Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ves set make run IMAGE=<name> resolves bare filenames against website/possitives, or accepts any absolute/relative image path. Output still lands in output/<stem>/ via pipeline.py's own default. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sam3_text_occluderwas missing fromMASK_FUSION_PRIORITY, letting oversized InstaFormer masks silently win over correct SAM3-text masksUSE_OCCLUDER_CLICK=Falsedefault, old behavior still available via the flag)INPUT_PROMPT="horse"default that silently hinted every no-hint runflux_depth.py(two-stage depth-guided fill experiment, gated off by default — evidence showed it underperforms plain Flux-Fill on hard cases)Makefilefor one-command runs (make run IMAGE=<name>) against the curatedwebsite/possitivessetTest plan
make help/make list/ Makefile path resolution🤖 Generated with Claude Code