Evaluate selective text restoration

This commit is contained in:
Victor Kuznetsov
2026-08-15 12:20:25 -07:00
parent f8003f505a
commit 8c00525946
19 changed files with 1779 additions and 14 deletions
+27 -2
View File
@@ -61,8 +61,25 @@ change even when the watermark is successfully disrupted.
Both are CUDA only and differ only in the global regeneration model: each
conditions that stage on a canny edge map, which preserves structure but not
identity or exact texture, and each then runs the same face stage.
`qwen-zimage` is the higher fidelity of the two. Both are large, slow, and may
still alter small text or difficult faces.
Existing face evaluations favor `qwen-zimage`, but there is no blanket fidelity
ordering across content types. A fixed-seed, three-scene text comparison at the
profile defaults found no stable winner: SDXL won one poster, Qwen won one, and
the Chinese sign tied. Both are large, slow, and may still alter small text or
difficult faces. The measurements and their OCR and oracle caveats are tracked
in [`data/evaluations/fidelity/`](../data/evaluations/fidelity/README.md).
A global Z-Image Turbo prototype preserved text substantially better at low
strength, but it has no useful cross-provider operating point and is not a
supported profile. The evaluated text restorers also remain research-only:
fresh-font and silhouette variants visibly changed typography, while the
higher-fidelity `vae-glyphs` route still requires verified strings, line
geometry, a separately generated donor, and an independently clean global
anchor. Automatic OCR and line-box proposals are not reliable enough to remove
those requirements, and the exact oracle results do not establish a general
mask, seed, or provider operating range. Qwen-Image-2.0 is hosted-only and
exposes no equivalent low-strength denoise control. Exact experiments, controls,
and pass rates are kept in
[`text-protection-research.md`](text-protection-research.md) and the
[`fidelity` evaluation record](../data/evaluations/fidelity/README.md).
### Removal cannot be verified locally for proprietary SynthID
@@ -175,6 +192,14 @@ certified at a fixed seed. The live resolver is
| `qwen-zimage` | CUDA only, large model stack, and limited broad certification across seeds and content. |
| `sdxl-zimage` | CUDA only. Its strength ladder is flat per vendor, not a resolution curve, because flat values are what was measured. |
The evaluated text-restoration prototypes are not optional production stages.
OCR plus LaMa recovered literal poster text but changed fonts and worsened whole-image
fidelity. Restricting it to OCR-mismatched lines improved the tradeoff but still
left a local shadow on one poster. The published AnyText2 SD1.5 checkpoint
substituted Chinese characters and increased CER on the sign fixture. AnyText2XL
is not published, and the released wrapper truncates individual text lines after
20 characters.
The `controlnet`, `sdxl`, `qwen` and `default` profiles were removed, not aliased
onward: a retired name is rejected at parse time rather than routed into a profile
the caller never chose. There is no `--model`, `--steps`, `--guidance-scale`,
+28
View File
@@ -949,6 +949,34 @@ orchestration, YuNet integration, SAM selection, masks, sizing helpers, and pixe
compositing are implemented for this runtime. Changing a calibrated model input
requires the same provider-oracle and identity evaluation as a model change.
A matched stage-isolation check on the 18-face Gemini portrait grid confirms the
division of responsibility. The visible-cleaned, metadata-stripped control and the
Z-Image face-only output were both SynthID-positive; Qwen global-only and the full
Qwen-then-Z-Image output were both clean. The face stage raised identity cosine from
0.589 to 0.852 and reduced face LPIPS from 0.217 to 0.050 without reintroducing a
detectable whole-image signal. Thus Z-Image is a masked fidelity repair stage here,
not the watermark-removal stage. Exact hashes, metrics, strengths, and the one-fixture,
one-seed caveat are recorded in
[`data/evaluations/fidelity/face-stage-isolation-2026-08-13.csv`](../data/evaluations/fidelity/face-stage-isolation-2026-08-13.csv).
The public Synthid-Bypass v2 graph was subsequently audited at upstream commit
`3007d035`. Its saved-output path confirms the same division: Qwen-Image-2512
Lightning plus Canny is global, and Z-Image Turbo exists only inside the masked
face detailer. The connected face path is YOLOv8-face plus SAM; the MediaPipe nodes
described by the upstream README and the 1.2-megapixel normalization node do not
reach `SaveImage`. Upstream also applies its adaptive face strength directly,
whereas this implementation multiplies it by `FACE_DENOISE_SCALE = 0.5`.
A close reproduction on the same portrait fixture kept the control positive and
made both Qwen global-only and full Qwen-then-Z-Image outputs clean. Applying the
upstream-strength face pass raised identity from 0.589 to 0.783 and reduced face
LPIPS from 0.217 to 0.083, but remained worse than this profile's 0.852 and 0.050.
The published upstream pair 12 was also independently checked positive before and
clean after, with 0.975 identity. Exact workflow provenance, hashes, metrics,
oracle outcomes, and the DiffSynth/GGUF, scheduler, detector, and seed caveats are
recorded in
[`data/evaluations/fidelity/upstream-v2-reproduction-2026-08-13.csv`](../data/evaluations/fidelity/upstream-v2-reproduction-2026-08-13.csv).
### SDXL plus Z-Image
[`_internal/sdxl_zimage_pipeline.py`](../src/remove_ai_watermarks/_internal/sdxl_zimage_pipeline.py)
+200
View File
@@ -143,3 +143,203 @@ Deep-research workflow run `wf_118b9a03-3eb` (2026-05-29). Findings adversariall
(2/3 refutes required to kill a claim). This note records research only; no code change is
implied until a prototype validates fidelity and the SynthID-scrub guarantee on the
restored output.
## 2026-08-13 OCR plus LaMa prototype
A lightweight version of the recommended two-stage architecture was tested on
the three tracked text fixtures. It used the already-clean Qwen result as the
base, recognized the source text, removed source and Qwen glyph contours with
LaMa, and rendered the recognized strings as fresh pixels. No source pixels
were pasted back.
The result validates only part of the hypothesis. Character-weighted CER on the
two multilingual posters fell from 0.338/0.305 to 0.007/0.007, and OpenAI Verify
remained clean for both matched Qwen and restored pairs. However, replacement
fonts changed the design, whole-image LPIPS worsened by 0.067 on each poster,
and the light poster retained a shadow in one small English line. On the Chinese
sign, punctuation errors moved CER from 0.074 to 0.111. The Google verifier run
was inconclusive because the available account detected both the restored image
and the byte-identical Qwen control that a previous account had called clean.
The experiment supports a proper glyph-conditioned restorer, not shipping the
plain OCR/system-font compositor. Exact hashes, metrics, masks, and provider
verdicts are tracked in
[`data/evaluations/fidelity/text-restoration-2026-08-13.csv`](../data/evaluations/fidelity/text-restoration-2026-08-13.csv).
## 2026-08-13 AnyText2 follow-up
The official AnyText2 SD1.5 checkpoint was then tested as the glyph-conditioned
restorer. Its ModelScope entry and code are Apache 2.0, and the downloaded
checkpoint matched the published SHA-256. An official blackboard edit completed
successfully before the fixture run, establishing that the runtime reproduced
the model rather than silently exercising a fallback.
On the Chinese sign, a three-line local edit over the exact Qwen output scored
CER 0.185 under the standard detector. Font mimic from the source glyph masks
scored 0.222. Whole-image LPIPS changed from 0.289 to 0.338 and 0.345 respectively.
A padded crop-recognition check showed why the comparison matters: Qwen contained
the full correct text and scored 0.000, while default AnyText2 still scored 0.074
with two substituted characters and mimic remained at 0.222. The provider oracle
was deliberately not called because these variants had already failed the
content-fidelity gate.
AnyText2 is therefore not the missing production restorer in its published form.
The negative result is narrower than the model family: only the SD1.5 checkpoint
is public, while AnyText2XL remains listed as future work. The current wrapper
also truncates each quoted text line to 20 characters, which prevents a direct
test of several tracked English and Russian poster lines. Exact model provenance,
output hashes, and metrics are recorded in
[`data/evaluations/fidelity/anytext2-restoration-2026-08-13.csv`](../data/evaluations/fidelity/anytext2-restoration-2026-08-13.csv).
The same cross-check exposes a measurement bug in the earlier lightweight
restoration result. Paddle detection made tight boxes that omitted the final
Chinese full stop from two lines, producing Qwen CER 0.074 although the pixels
and padded recognition were correct. Adding 16-32 pixels of horizontal context
restored every punctuation mark. A deterministic rerender using the full OCR
strings and the closest of nine mask-scored CJK fonts also reached detector CER
0.000, but its heavier Hiragino Sans GB W6 glyphs raised LPIPS from 0.289 to 0.327.
The actionable design is selective restoration: compare padded source and output
recognition first, and preserve the Qwen output when they already match.
That policy was tested on the two multilingual posters. A manual prototype kept
the lines whose padded source and Qwen recognition agreed and rerendered only the
changed lines. The edited mask fell from 15.4%/17.0% in the full compositor to
5.5%/5.5%. On a single Paddle `en+ru+ch` route, CER changed from 0.378/0.413 for
Qwen to 0.101/0.112, while LPIPS was only 0.120/0.103 rather than the full
compositor's 0.174/0.162. The different OCR route is intentional and all three
variants were remeasured through it; these CER values are not directly
comparable with the earlier Vision/Paddle hybrid results.
Both selective outputs returned `No OpenAI signals detected` in OpenAI Verify,
and the original light poster returned `Generated with OpenAI tools` immediately
afterward as the positive control. The dark poster was visually clean. The light
poster still showed one local old-text shadow, so mask construction remains the
blocking defect. Exact hashes, metrics, mask fractions, and oracle controls are
in
[`data/evaluations/fidelity/selective-text-restoration-2026-08-13.csv`](../data/evaluations/fidelity/selective-text-restoration-2026-08-13.csv).
Uniformly expanding every selected glyph mask by two pixels removed that light
poster shadow and moved CER from 0.101 to 0.081 without a meaningful LPIPS cost.
It also expanded the edited area from 5.5% to 7.0%, and the identical rule made
the dark poster worse at CER 0.147 rather than 0.112. Those follow-up bytes have
not been oracle-checked. The next prototype should detect residual source glyphs
per line and expand only the failing component, rather than introducing another
poster-wide tuning constant.
The manual selection was then replaced with per-line padded recognition. A line
is left untouched only when the source recognizer is sufficiently consistent
with the verified line and normalized source/candidate recognition agree
exactly. The automatic rule reproduced the manual selection on the dark poster
and correctly kept one additional large Russian line on the light poster. It
reduced that poster's effective edited area from 5.5% to 4.1%.
Mask cleanup became a measured second pass rather than a global dilation. After
the first LaMa erase, the prototype finds contrast that remains specifically at
the original glyph positions, dilates only that residual, and erases it before
fresh text is drawn. This removed the visible double glyphs from both posters.
The automatic outputs scored LPIPS 0.113/0.104 and detector CER 0.123/0.119, with
effective edited fractions of 4.1%/5.7%. The light aggregate CER is pessimistic:
the page detector fragments its untouched Cyrillic line into Latin-like pieces,
while the padded Russian recognizer returns the exact expected text.
OpenAI Verify returned `No OpenAI signals detected` for both new hashes and then
`Generated with OpenAI tools` for the original light poster in the same browser
sequence. Reproducing the prototype from the tracked script exposed harmless
ONNX rounding on the light image: 386 pixels differed by at most one channel
value from the initially checked hash. The exact tracked output hash
`900def5a...` was therefore submitted separately, returned clean, and was
followed immediately by another positive source result. The dark tracked output
was byte-identical to the initially checked hash.
The Chinese sign provides a no-edit control for the selector. Detector boxes for
its three large lines overlap vertically, so Latin-style vertical padding
incorrectly mixed neighboring lines. Horizontal-only CJK padding captured the
terminal punctuation without mixing neighbors and made source and candidate
recognition agree exactly on all three lines.
The script then produced a zero mask and copied the Qwen candidate byte for byte.
This prevents the heavier-font regression seen in the earlier CJK compositor,
but does not resolve the unavailable Google-negative oracle control.
The result clears the measured OpenAI gate without a manual line selection, but
is not a production design yet. It still assumes verified source strings and
line boxes, relies on macOS system fonts, and needs evaluation on uncurated
layouts, rotated text, false OCR matches, automatic line-box discovery, and a
reproducible Google-negative control.
The later source-silhouette experiment removed the font lookup but did not meet
the actual visual requirement. Native-size review found changed stroke weight,
color variation, edge antialiasing, and decorative details even where crop OCR
was exact. A narrower `vae-glyphs` experiment uses the silhouette only as a
support mask: exact pixels come from a Qwen-VAE reconstruction, while a fresh
flat-color silhouette supplies only the outer edge beneath that core. Across 48
typography cases (548 annotated lines), this improved glyph-edge MAE in 48/48
and text-box SSIM in 47/48. The median values moved from 37.59 to 32.42 and from
0.854 to 0.914 respectively. One separate untracked core-only output with a
1.43% donor area returned `No OpenAI signals detected`; the tracked script then
reproduced those exact bytes. A 0.5-pixel feathered sibling with 2.75% nonzero
donor area improved mean text-box SSIM from 0.957 to 0.960, with a 0.918 minimum
across 15 verified lines, while full-image RGB SSIM reached 0.864. Crop OCR
recovered from 7/15 exact lines on the raw pass to 14/15, equal to the source's
own recognizer floor. Whole-image LPIPS was 0.082, but only 0.108% of pixels
remained exactly equal to the source and the detected face's Laplacian-variance
ratio was 0.670, confirming residual global smoothing. A same-session
OpenAI Verify sequence detected the exact source control in 1/1 check, returned
clean for the raw global pass and clean-fidelity anchor in 1/1 each, and returned
clean for the feathered output in 3/3 repeats. The tracked script reproduced
that feathered file byte for byte. This proves two materially better exact-output
Pareto points, not a general operating range. The 48 matrix outputs and other
mask sizes remain oracle-unverified.
The first Google oracle sample did not transfer. For the synthetic CJK sign,
two separate work accounts detected SynthID in both the resaved positive source
control and the exact Qwen-VAE donor candidate. The candidate's text-box SSIM
improved from 0.791 to 0.835 and its glyph-edge MAE from 35.48 to 22.49, but its
3.67% donor layer did not create a clean operating point. The Qwen silhouette
base was already detected, as was the earlier original-sign Qwen baseline in the
same account. The measured cause is therefore insufficient global Google
regeneration, not a demonstrated watermark regression from the text donor.
Google needs a stronger oracle-clean global anchor before the narrow donor can
be evaluated there.
A targeted follow-up supplied that missing anchor for one CJK case. An explicit
Qwen global pass at strength 0.30 returned no reliable SynthID signal in Gemini,
while the matched source control was detected. Applying the 0.5-pixel
`vae-glyphs` layer to that clean anchor changed 1.17% of the image and raised
mean text-box SSIM from 0.765 to 0.964 (minimum 0.963), with mean text-box MAE
falling from 20.74 to 5.38. The post-donor output then returned clean in 3/3
Gemini checks across two work accounts. A separate 18-face fixture with four
tiny UI-text lines also had a clean strength-0.30 anchor; its donor layer changed
0.70% of the image, raised mean text-box SSIM from 0.617 to 0.976 (minimum
0.972), and returned clean in 3/3 checks across the same two accounts. One
quota-exceeded response is excluded from both pass rates. These are two exact
oracle-certified outputs, not a general operating range: other layouts, masks,
strengths, seeds, and donor areas remain unverified.
An automatic-box follow-up merged Paddle word detections by vertical overlap.
It found exactly 20/20 poster lines and 3/3 sign lines, with mean IoU 0.857,
0.847, and 1.000 against the verified boxes. That structural match was not
sufficient: reusing the annotation crop padding changed recognition decisions,
reduced preserved dark-poster lines from 7 to 4, and expanded its edited
fraction from 5.7% to 11.2%.
A recognition-only sweep isolated the crop sensitivity. Limiting vertical
padding around detector boxes to 8-12% of line height reproduced the verified-
box decision vectors on both posters; 10% was used for a full follow-up. It kept
8/20 and 7/20 lines with edited fractions of 4.1% and 5.7%, and visual inspection
found no double glyphs. Whole-image LPIPS remained 0.113/0.104, but detector CER
was 0.127/0.154 instead of 0.123/0.119. The dark regression failed the fidelity
gate, so these hashes were not submitted to the provider oracle. The opt-in flag
remains only to reproduce the negative result. Count, IoU, and matching decision
vectors are therefore insufficient gates for automatic boxes; the next design
needs box rectification or recognition stability under crop jitter before it
can replace verified geometry.
Removing verified strings was tested separately with an annotation-seed dry
run. It detects boxes, chooses `en`, `ru`, or `ch` from Unicode script, and
accepts a draft only when three crop paddings normalize identically and every
confidence is at least 0.85. One execution proposed 20 and 18 poster lines, but
exact-text precision against the held-out annotations was only 90.0% and 94.4%.
The stable errors were punctuation: one lost English comma and an ideographic
comma consistently replaced by ASCII. Thus crop agreement and confidence do
not verify literal text. The helper is retained only to seed annotations; every
proposal needs manual review before it can enter the restoration compositor.