Commit Graph
368 Commits
Author SHA1 Message Date
github-actions[bot] 63d7cfa0a5 Sync conda recipe with v0.22.0 2026-07-31 17:43:40 +00:00
Victor Kuznetsov 08dc078d91 Release 0.22.0 with composable feature extras v0.22.0 2026-07-31 10:39:13 -07:00
Victor Kuznetsov 9c9e81c756 Compact CLAUDE.md and route development guidance 2026-07-30 18:32:25 -07:00
Victor Kuznetsov fc177bacde Correct OpenCV Dependabot compatibility cutoff 2026-07-30 18:18:49 -07:00
Victor Kuznetsov 0c4b26bb77 Fix OpenCV Dependabot compatibility bound 2026-07-30 16:29:29 -07:00
Victor Kuznetsov 3d941069e5 Keep Dependabot updates within compatible dependency lines 2026-07-30 16:21:50 -07:00
Victor Kuznetsov 4e97076b22 Merge external metadata evidence into main 2026-07-30 12:49:06 -07:00
github-actions[bot] a67b209d66 Sync conda recipe with v0.21.2 2026-07-29 23:48:36 +00:00
Victor Kuznetsov 7c9bec0eba Ignore collector diagnostics in metadata evidence v0.21.2 2026-07-29 16:46:42 -07:00
github-actions[bot] 37f3b3b1c9 Sync conda recipe with v0.21.1 2026-07-29 21:34:11 +00:00
Victor Kuznetsov 4ef180541f Add external metadata evidence ingestion v0.21.1 2026-07-29 14:32:25 -07:00
github-actions[bot] c013704ded Sync conda recipe with v0.21.0 2026-07-29 20:17:17 +00:00
Victor Kuznetsov 408c4c9d5d Separate provenance extraction and detection, release 0.21.0 v0.21.0 2026-07-29 13:13:39 -07:00
github-actions[bot] 28d23a3023 Sync conda recipe with v0.20.2 2026-07-28 19:14:22 +00:00
Victor Kuznetsov 59823b2eaf Recover malformed metadata containers, release 0.20.2 v0.20.2 2026-07-28 12:12:26 -07:00
Victor Kuznetsov 1d333fe855 Use a dedicated ComfyUI release token 2026-07-26 12:11:35 -07:00
Victor Kuznetsov 5ea160f4ce Include ComfyUI in library releases 2026-07-26 11:56:09 -07:00
github-actions[bot] 643557b7bf Sync conda recipe with v0.20.1 2026-07-26 18:41:23 +00:00
Victor Kuznetsov e562b440db Improve Qwen face fidelity, release 0.20.1 v0.20.1 2026-07-26 11:39:29 -07:00
Victor Kuznetsov ab525c1b90 Add global-only preload for qwen-zimage 2026-07-26 10:52:26 -07:00
Victor Kuznetsov 685f0679bd Automate conda recipe synchronization 2026-07-25 21:57:22 -07:00
Victor Kuznetsov d21dc62bbb Sync conda recipe with v0.20.0 2026-07-25 21:32:52 -07:00
Victor Kuznetsov 03cd00f132 Restructure documentation, validate metadata removal, consolidate assets v0.20.0 2026-07-25 21:08:04 -07:00
Victor Kuznetsov 214c9bb3e7 Add Tencent Yuanbao visible watermark removal 2026-07-25 20:52:15 -07:00
Victor KuznetsovandGitHub 952ce822fd Merge pull request #64 from salomonMuriel/feature/cuda-cpu-offload
Add --cpu-offload flag for low-VRAM CUDA cards
2026-07-25 19:08:24 -07:00
Victor Kuznetsov fbca7f7ed9 Sync CPU offload with dependency updates 2026-07-25 19:05:41 -07:00
Victor KuznetsovandGitHub 51d222f4ea Merge pull request #63 from wiltodelta/dependabot/uv/minor-and-patch-e56a0901c7
chore(deps): bump the minor-and-patch group across 1 directory with 5 updates
2026-07-25 19:04:06 -07:00
Victor Kuznetsov d6cf5f4e84 Sync dependency updates with current main 2026-07-25 19:01:40 -07:00
Victor Kuznetsov b8b69d93be Finish CPU offload support on current main 2026-07-25 18:44:44 -07:00
Victor Kuznetsov 88949c3c30 Isolate Qwen Z-Image tests from GPU extras 2026-07-25 17:13:04 -07:00
Victor Kuznetsov 43312b04eb Exclude Markdown from Ruff formatting 2026-07-25 17:10:47 -07:00
Victor Kuznetsov b0419a9d8a Merge Qwen Z-Image pipeline into main 2026-07-25 17:00:05 -07:00
Victor Kuznetsov b6204a24ce Add high-fidelity Qwen Z-Image removal pipeline 2026-07-25 16:53:22 -07:00
Victor KuznetsovandClaude cdec348349 Add v2 forensic features to the scorer, split without hash leakage
Train now dedups by sha256 (earliest date wins), splits by hash group,
and drops post-cutoff rows whose hash was seen in training, so neither
holdout reports memorized duplicates. The feature schema is explicit
(v1 = the original 97 structural features, v2 adds CFA peaks, DCT AC
histograms and JPEG quant/Huffman/scan stats), stored in the bundle and
read back at scoring time; legacy bundles default to v1. Vectors are
fixed-width with NaN padding, so a sparse record no longer shifts every
column. Scoring runs in batches instead of one predict_proba per record.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 19:24:39 -07:00
dependabot[bot]andGitHub bb9f9c959d chore(deps): bump the minor-and-patch group across 1 directory with 5 updates
Bumps the minor-and-patch group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [pillow-heif](https://github.com/bigcat88/pillow_heif) | `1.4.0` | `1.5.0` |
| [c2pa-python](https://github.com/contentauth/c2pa-python) | `0.36.0` | `0.37.1` |
| [transformers](https://github.com/huggingface/transformers) | `5.13.1` | `5.14.1` |
| [huggingface-hub](https://github.com/huggingface/huggingface_hub) | `1.23.0` | `1.24.0` |
| [ruff](https://github.com/astral-sh/ruff) | `0.15.21` | `0.16.0` |



Updates `pillow-heif` from 1.4.0 to 1.5.0
- [Release notes](https://github.com/bigcat88/pillow_heif/releases)
- [Changelog](https://github.com/bigcat88/pillow_heif/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bigcat88/pillow_heif/compare/v1.4.0...v1.5.0)

Updates `c2pa-python` from 0.36.0 to 0.37.1
- [Release notes](https://github.com/contentauth/c2pa-python/releases)
- [Changelog](https://github.com/contentauth/c2pa-python/blob/main/docs/release-notes.md)
- [Commits](https://github.com/contentauth/c2pa-python/compare/v0.36.0...v0.37.1)

Updates `transformers` from 5.13.1 to 5.14.1
- [Release notes](https://github.com/huggingface/transformers/releases)
- [Commits](https://github.com/huggingface/transformers/compare/v5.13.1...v5.14.1)

Updates `huggingface-hub` from 1.23.0 to 1.24.0
- [Release notes](https://github.com/huggingface/huggingface_hub/releases)
- [Commits](https://github.com/huggingface/huggingface_hub/compare/v1.23.0...v1.24.0)

Updates `ruff` from 0.15.21 to 0.16.0
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.15.21...0.16.0)

---
updated-dependencies:
- dependency-name: c2pa-python
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: huggingface-hub
  dependency-version: 1.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: pillow-heif
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: ruff
  dependency-version: 0.15.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: transformers
  dependency-version: 5.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-23 23:25:34 +00:00
Victor Kuznetsov 11afe68411 chore(release): v0.19.0 v0.19.0 2026-07-23 16:20:27 -07:00
Victor Kuznetsov c11181b9b5 Detect and attribute Bria AI, fal.ai, and Apple Photos Clean Up
Corpus-mined vendor gaps (42k-file metadata scan, 2026-07-23):
- Bria AI signs C2PA as "Bria Artificial Intelligence" with source type
  empty (no trainedAlgorithmicMedia), so identify was completely blind;
  registered with asserts_ai like Dreamina.
- fal.ai ("fal - Features & Labels Inc.", fal-ai/<model> generators)
  was detected via the source type but never attributed; registered,
  also asserts_ai as a pure generative platform.
- Apple Photos Clean Up (Apple Intelligence object removal) was detected
  as a generic made-with-AI tag; now attributed as an AI edit via the
  photoshop:Credit marker, and the credit value joins
  AI_GENERATOR_TOKENS so removal strips it in parity.
Each new test was verified red without its fix.
2026-07-23 16:15:48 -07:00
Victor Kuznetsov eb544806f6 Add AI-generation scorer trained on metadata-labeled corpus
scripts/ai_score.py trains a gradient-boosted classifier on labels
derived from the scan_dataset metadata (C2PA AI generators, TC260,
local pipelines vs camera/screenshot/editor output) and scores every
file from pixel and container statistics alone, so metadata-stripped
files still get a score. Temporal holdout on the production corpus:
AUC 0.966 / AP 0.988. CLIP ViT-L/14 was evaluated as an alternative
and lost on both accuracy (0.82) and cost, so the model uses the
structural features the scanner already collects; scoring is CPU-only
and I/O-bound.
2026-07-23 16:01:35 -07:00
Salomón MurielandClaude Opus 4.8 39fdd59f6c Add --cpu-offload flag for low-VRAM CUDA cards
The invisible/SynthID diffusion pass loads the whole SDXL fp16 pipeline
into VRAM via `pipeline.to("cuda")`. On an 8 GB card the weights alone
(~7 GB) leave no room for activations, so the run OOMs and there is no
in-tool way to recover short of falling back to CPU (~9 min/image).

Add an opt-in `--cpu-offload` flag (default off) that calls diffusers'
`enable_model_cpu_offload()` instead: submodules are streamed to the GPU
on demand, dropping peak VRAM to roughly the largest single submodule at
the cost of per-step transfers. CUDA-only; a no-op on cpu/mps. Threaded
through `invisible`, `all`, and `batch` to keep the knob set identical
across the three, mirroring the existing `--device`/`--pipeline` options.

Measured on a GTX 1070 Ti (8 GB): `invisible --pipeline sdxl --cpu-offload`
runs the SynthID scrub on-GPU in ~2.5 min vs ~9 min on CPU, where the
default full-VRAM path OOMs.

Test drives the placement decision with a mock pipeline (no model/GPU),
gated on torch so it runs under the `gpu` extra and skips the core CI
matrix, consistent with the model-running test policy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 16:06:43 -05:00
Victor Kuznetsov dfe69772cd Polish the scanner after review: shared b64 helper, tri-state pixel mode
Route the pixel layer's base64 through the capped _b64 helper, replace
the pixels/pixels_full booleans with one pixel_mode parameter, record a
pixel skipped marker on oversized files, read EXIF from the already-read
bytes instead of re-reading the file, chunk the noise residual
convolution and replace the mgrid with 1D broadcast in the FFT features
(bit-identical values, ~300 MB less peak memory at 2048px), and fix the
raw-only docstring to account for the derived pixel layer.
2026-07-23 11:54:08 -07:00
Victor Kuznetsov 68fb3dded6 Fix numpy-free metadata mode after the pixel-layer merge
Guard module-level numpy touchpoints so the metadata-only mode imports
and runs without numpy installed (deferred annotations, lazy DCT basis);
pixel modes now exit early with a clear numpy requirement message.
2026-07-23 11:13:13 -07:00
Victor Kuznetsov 47ef60c2a1 Add optional pixel forensics layer to the dataset scanner
--pixels adds aggregate, non-reconstructable pixel statistics (block-DCT
histograms with Benford deviation, high-pass noise stats, FFT band
energies and CFA peaks, ELA stats, gradient and color histograms) plus
per-section timing for pipeline latency planning. --pixels-full adds the
privacy-lifting artifacts behind an explicit flag (perceptual hash,
128px thumbnail, coarse ELA/noise-residual/FFT-phase maps). Expensive
maps are computed once and shared between the scalar and artifact paths
(2.2x speedup vs the first split implementation). numpy is required only
for the pixel modes; the metadata-only mode stays numpy-free.
2026-07-23 11:06:45 -07:00
Victor Kuznetsov a981eb84b1 Make the dataset scanner raw-only and harden format sniffing
Strip all derived output: the library verdict, the XMP edit-trail
parse, and the IJG quality estimate. The script now collects raw bytes
plus mechanical container decodes only, is fully standalone (no
remove_ai_watermarks import), and resumes interrupted runs. Add GIF,
BMP, and TIFF magic bytes to sniff_format (GIF files in the wild were
reported as unknown). Validated on the full 42k-file corpus: 100%
coverage, zero error records.
2026-07-22 20:32:36 -07:00
Victor Kuznetsov df62800bf1 Add standalone dataset metadata/forensics scanner script
Single-file read-only scanner producing one JSONL record per image:
AI verdict via identify (metadata-only, no visible marks), full EXIF/
IPTC/XMP/PNG/JPEG/WebP/ISOBMFF inventories, C2PA store, JPEG encoder
forensics (quant tables, IJG quality, scan script, Huffman, subsampling),
XMP edit-trail fields, hashes/timestamps, macOS download provenance,
Live Photo pairing id. Runs standalone (pillow/piexif/c2pa-python) with
the library optional; supports gzip output, resume after interruption,
and head-only scanning of oversized files.
2026-07-22 17:53:02 -07:00
Victor Kuznetsov 80cdaff2d5 chore(release): v0.18.0 v0.18.0 2026-07-22 13:17:00 -07:00
Victor Kuznetsov f1a5eecf98 Register RunningHub, Baidu, and LibLibAI visible marks; park Qingyan and MiniMax (measured)
New engines, each calibrated on its TC260 USCC cohort and validated by a
full-corpus sweep (42009 files):
- runninghub: top-left corner (new corner="tl"), faint mid-gray text via
  the new raw-grayscale "gray" detection front-end, anchor-position gate
- baidu: text-run-only template (pill is a bright-blob magnet), load-bearing
  Doubao+Qwen rival margins, corner-extended footprint for the white tag
- liblib: bottom-center (new corner="bc"), Arial silhouette (font is the
  discriminative lever against latin UI text), logo-extended footprint

Qingyan parked (no clean-arm separation at any render/box), MiniMax/Hailuo
parked (1 visible frame, the xinghui rule); silhouettes kept as starting
points.
2026-07-22 13:03:03 -07:00
Victor Kuznetsov ba29eccc45 chore(release): v0.17.0 v0.17.0 2026-07-22 09:15:07 -07:00
Victor Kuznetsov 5d63b9161f Register the Kling 可灵AI 3.0 visible text mark; park Yuanbao and cat-logo (measured)
Kling (USCC cohort 91110108335469089C, n=30): kling_engine.py, gate 0.35
(clean p99 0.304 / max 0.320), strict-only, unimodal 0.12/short on the
shared ladder, fitted locate box, no rival margin (crossfire 1/400 doubao
below gate, 0 jimeng, 0 clean), parity 9/9 detect->fill->re-detect.
Suppresses the jimeng pill like doubao/qwen. identify gains visible_kling.

Yuanbao: measured negative -- the two-line italic block does not separate
from clean corners on either front-end at any render/box/font setting;
the fitted recipe stays in render_vendor_silhouettes.py MARK_OPTS.

cat-logo: cohort has only 2 unique carriers, parked on evidence; the
draw_catlogo silhouette already separates (0.50 vs clean max 0.333), so
registration is a gate pick once more uniques arrive.

vendor_mark_calibrate: --fit-geometry takes locate-box overrides (two-line
marks were clipped by the inherited box) and the aspect sweep reaches 0.62.
2026-07-22 08:49:06 -07:00
Victor Kuznetsov 3a659ededc chore(release): v0.16.0 v0.16.0 2026-07-21 18:35:04 -07:00
Victor Kuznetsov 008319c6a5 Register the Qwen 千问AI生成 visible text mark
Calibrated on the 117-frame TC260-producer cohort (vendor_cohort_harvest +
vendor_mark_calibrate, both committed here): per-mark 2-rung ladder
(0.78, 1.27) for the two measured size modes, fitted locate box (the mark
sits ~0.025 of the short side off the edge; doubao's box clipped the first
glyph), measured template aspect 0.26, gate 0.45 (clean p99 0.301).
Strict-only (the sub-gate band is non-Qwen banners), no rival margin
(0 cross-fires on 400 doubao / 298 jimeng / 286 clean frames).
83/83 real marks detector-clean after cv2 fill.

TextMarkConfig gains a per-mark ladder field; the shipped 3-rung default
is unchanged for every other mark.
2026-07-21 16:41:16 -07:00