
Gemini의 SynthID 탐지 리버스 엔지니어링
스펙트럼 분석을 통해 Google의 AI 워터마크를 발견, 탐지 및 정밀하게 제거
PitchHut에서 방문하세요
이 포크는 V3 우회를 위한 드래그 앤 드롭 데스크톱 앱을 추가합니다. 설정 후에는 명령줄이 필요 없습니다. 설정 및 사용법은 gui/README.md를 참조하세요.
SynthID는 픽셀 값에 직접 감지할 수 없는 패턴을 인코딩합니다. Gemini로 생성된 순수 흰색 이미지에서 워터마크는 거의 전체 신호입니다. 고주파 잔차를 증폭하면 다음과 같이 보입니다:
순수 흰색 Gemini 이미지에서 추출한 증폭된 SynthID 캐리어 패턴. 대각선 줄무늬는 워터마크의 공간 주파수 서명으로, 스펙트럼 공격의 대상입니다.
이 프로젝트는 Google Gemini로 생성된 모든 이미지에 포함된 보이지 않는 워터마크인 Google의 SynthID 워터마킹 시스템을 리버스 엔지니어링합니다. 신호 처리와 스펙트럼 분석만을 사용하여(독점적인 인코더/디코더에 접근하지 않고) 다음을 수행합니다:
gemini-3.1-flash-image-preview 및 nano-banana-pro-preview에 대한 모델별 프로파일, 6가지 단색 배경에 대한 색상 간 위상 컨센서스, 그리고 수동 Gemini 앱 탐지 집계에서 캐리어별 차감 강도를 조정하는 인간-인-더-루프 보정 루프VT-OxFF는 SynthID 워터마크가 이미지에 추가되는 과정을 볼 수 있는 정말 멋진 시각화 도구를 여기에 구축했습니다(저장소 설명에서도 확인 가능)!
6번의 반복적인 적대적 개발 라운드 후, Round 06의 bypass_v4_final / bypass_v4_nuke 파이프라인은 시각적으로 무손실 출력으로 gemini-3.1-flash-image-preview 및 nano-banana-pro-preview 이미지 모두에서 Gemini SynthID 탐지기를 무력화합니다.
왼쪽: Round 01 출력(gentle 스펙트럼 차감만). 오른쪽: Round 06 출력(final — VAE + 탄성 변형 + 스퀴즈 + 색상 + JPEG). 둘 다 인간의 눈에는 동일하게 보입니다. Round 06만이 SynthID 탐지기를 무력화합니다.
Round 06의 돌파구는 Gemini 앱이 자체적으로 발표한 실패 모드 목록을 공격 사양으로 취급한 데서 비롯되었습니다:
"AI 생성 이미지가 복잡한 콜라주의 일부이거나, 다른 요소 뒤에 레이어되어 있거나, 많은 다양한 텍스처와 패턴이 그 위에 배치된 경우, 탐지기는 전체 파일에서 특정 서명을 분리하는 데 어려움을 겪을 수 있습니다." — Gemini 앱, SynthID 탐지 도움말 텍스트
탄성 변형 단계는 픽셀 수준에서 이 효과를 시뮬레이션합니다. 부드럽고 저주파수인 무작위 왜곡 필드는 약 50픽셀 이웃 각각에 고유한 독립적인 서브픽셀 오프셋을 제공하여, 눈에 띄는 왜곡 없이 워터마크의 공간 위상 컨센서스를 조각냅니다.
V4는 훨씬 더 풍부한 데이터셋을 기반으로 구축된 코드북의 근본적인 재고입니다:
gemini-3.1-flash-image-preview 및 nano-banana-pro-preview에 대한 별도 프로파일(선택적 union 의사 모델 추가).black, white, blue, green, red, gray)과 콘텐츠 기준선으로 gradient 및 diverse.carrier_weights가 업데이트됩니다.각 주파수 빈 (fy, fx) 및 채널 ch에 대해:```
consensus(fy, fx, ch) = | mean_over_colors( exp(i * phase_color(fy, fx, ch)) ) |
`1.0`에 가까운 값은 해당 빈의 위상이 모든 단색 배경에 걸쳐 고정되어 있음을 의미하며, 이는 워터마크에만 해당됩니다. 콘텐츠 빈은 다양한 색조에 의해 위상이 무작위화되기 때문에 `< 0.3`으로 수렴합니다. 강화된 데이터셋으로 구축된 V4 코드북에서 콘텐츠 빈의 99% 이상이 기본 `tau=0.60` 임계값 아래에 있으므로 V4 용해기가 이를 전혀 건드리지 않습니다. — 이것이 PSNR을 회복하는 방법입니다.
### 2단계 릴리스 워크플로```mermaid
flowchart LR
dataset[reverse-synthid-dataset<br/>model x color x resolution] --> build[scripts/build_codebook_v4.py]
build --> codebook[artifacts/spectral_codebook_v4.npz]
codebook --> dissolve[scripts/dissolve_batch.py]
input[watermarked inputs] --> dissolve
dissolve --> variants[final / nuke variants]
variants --> gemini[Gemini app<br/>manual SynthID detection]
gemini --> feedback[detection feedback]
feedback --> calibrate[scripts/calibrate_from_feedback.py]
calibrate -->|updates carrier_weights| codebook
python scripts/build_codebook_v4.py
--root /path/to/reverse-synthid-dataset
--output artifacts/spectral_codebook_v4.npz
python scripts/dissolve_batch.py
--input ./to_clean/
--output ./runs/round_06/
--codebook artifacts/spectral_codebook_v4.npz
--model gemini-3.1-flash-image-preview
--strengths final nuke
### Round-06 공격 프리셋
`--strengths`를 통해 두 가지 프리셋을 사용할 수 있습니다:
| 프리셋 | VAE 패스 | 탄성 α | 압축 | JPEG 체인 | PSNR 하한 |
|:------:|:----------:|:---------:|:-------:|:----------:|:----------:|
| `final` | 1 | 1.8 px | 90 % | q=92→88 | 14 dB |
| `nuke` | 2 | 2.8 px | 82 % | q=88→84→90 | 11 dB |
두 프리셋 모두 동일한 7단계 파이프라인을 쌓습니다:
1. **VAE 왕복** (Stable Diffusion `sd-vae-ft-mse`) — SynthID 디코더가 훈련된 적 없는 자연 이미지 다양체에서 이미지를 투영합니다 (Gowal et al. 2026, §6.1)
2. **탄성 변형** — 부드러운 저주파 무작위 워프 필드, Gemini 자체가 인정하는 "콜라주 조각화" 실패 모드를 시뮬레이션합니다
3. **전역 기하학적 조합** — 하나의 아핀 워프에서 작은 회전 + 확대/축소 + 픽셀 이동
4. **크기 조절 압축** — 다운샘플(AREA) → 업샘플(LANCZOS), 서브픽셀 워터마크 정보 제거
5. **색상 대비 조정** — 밝기/대비/채도/색조 미세 조정
6. **잔차 위상 FFT 차감** — 블로그 범용 + 코드북 수집 캐리어 빈, 상한 제한
7. **JPEG 체인 + 휘도 노이즈 + 양방향** — 강한 압축/재인코딩 방해
모든 단계는 독립적으로 PSNR 게이트가 적용됩니다. 품질을 하한 아래로 떨어뜨리는 단계는 자동으로 롤백됩니다.
### V4 코드북 구조
프로파일은 `(model, H, W)`로 키가 지정됩니다. 각 프로파일은 다음을 저장합니다:
| 필드 | 형태 | 설명 |
|------------------------|----------------|--------------------------------------------------------|
| `consensus_coherence` | `(H, W, 3)` | 기본 캐리어 마스크 (교차 색상 위상 합의). |
| `consensus_phase` | `(H, W, 3)` | 색상 전반의 평균 단위 위상 각도. 차감 템플릿. |
| `inverted_agreement` | `(H, W, 3)` | 쌍별 `abs(cos(phase_diff))`, `black<->white`에 대해 가중치 적용. |
| `avg_wm_magnitude` | `(H, W, 3)` | 합의 색상 전반의 평균 크기. |
| `content_baseline` | `(H, W, 3)` | `diverse/` + `gradient/`에서 가져옴 — 휘도 블렌딩에 사용. |
| `carrier_weights` | `(H, W, 3)` | **활성**. `consensus^2 * (0.5 + 0.5 * agreement)`로 시작. 교정 루프에 의해 업데이트됨. |
| `n_refs_per_color` | `{color: int}` | 색상별 참조 횟수. |
저장 형식은 v3의 압축 rfft + `float16/uint8` 인코딩을 재사용합니다. 2개 모델 × 7개 해상도에 걸친 14개 프로파일 코드북은 디스크에서 약 220MB입니다.
### V4 탐지기 (신뢰성 검사)
수동 Gemini 검증에 시간을 소비하기 전에, V4 코드북 자체의 합의에 대해 우회 출력의 신뢰성 검사를 수행하세요:```python
from robust_extractor import RobustSynthIDExtractor
from synthid_bypass_v4 import SpectralCodebookV4
cb = SpectralCodebookV4()
cb.load('artifacts/spectral_codebook_v4.npz')
ext = RobustSynthIDExtractor()
result = ext.detect_from_v4_codebook(image_rgb, cb,
model='nano-banana-pro-preview')
print(result.is_watermarked, result.confidence, result.phase_match)
1024x1024 정확 매칭 경로에서 워터마크가 있는 경우 conf=0.91, phase_match=0.65, 공격적인 V4 디졸브 후에는 conf=0.02, phase_match=0.31이 나타납니다.
V3는 이에 의존하는 모든 사용자를 위해 변경 없이 리포(src/extraction/synthid_bypass.py, bypass_v3)에 그대로 남아 있습니다.
멀티 해상도 워터마크 추출을 개선하기 위해 Nano Banana Pro로 생성된 순수 검정 및 순수 흰색 이미지를 적극적으로 수집하고 있습니다.
다음 조건의 이미지를 생성할 수 있다면:
gemini_black_nb_pro/ (검정)gemini_white_nb_pro/ (흰색)이 참조 이미지는 매우 중요합니다:
새로운 해상도의 이미지 150–200장만으로도 탐지 및 제거 성능을 크게 향상시킬 수 있습니다.
참조 이미지는 git 리포를 가볍게 유지하기 위해 Hugging Face에 호스팅됩니다:```bash pip install huggingface_hub python scripts/download_images.py # download all python scripts/download_images.py gemini_black # download specific folder
데이터셋: [huggingface.co/datasets/aoxo/reverse-synthid](https://huggingface.co/datasets/aoxo/reverse-synthid)
---
## 주요 발견 사항
### 워터마크는 해상도에 따라 달라집니다
SynthID는 이미지 해상도에 따라 **다른 절대 위치**에 캐리어 주파수를 삽입합니다. 1024x1024에서 구축된 코드북은 1536x2816 이미지의 워터마크를 직접 제거할 수 없습니다 — 캐리어가 완전히 다른 빈(bin)에 있기 때문입니다.
| 해상도 | 최상위 캐리어 (fy, fx) | 일관성 | 출처 |
|:----------:|:--------------------:|:---------:|:------:|
| **1024x1024** | (9, 9) | 100.0% | 검은색 100 + 흰색 100 참조 |
| **1536x2816** | (768, 704) | 99.6% | 워터마크된 콘텐츠 이미지 88개 |
이것이 V3 코드북이 **해상도별로 별도의 프로파일**을 저장하고 우회 시 자동으로 선택하는 이유입니다.
### 위상 일관성 — 고정된 모델 수준 키
동일한 Gemini 모델의 모든 이미지에서 워터마크의 위상 템플릿은 **동일**합니다:
- **녹색 채널**이 가장 강한 워터마크 신호를 전달합니다.
- 캐리어에서 **이미지 간 위상 일관성**: >99.5%
- **흑백 교차 검증**은 |cos(phase_diff)| > 0.90을 통해 실제 캐리어를 확인합니다.
### 캐리어 주파수 구조
1024x1024(흑백 참조 기준)에서 최상위 캐리어는 저주파 그리드에 위치합니다:
| 캐리어 (fy, fx) | 위상 일관성 | 흑백 일치도 |
|:-----------------:|:---------------:|:-------------:|
| (9, 9) | 100.00% | 1.000 |
| (5, 5) | 100.00% | 0.993 |
| (10, 11) | 100.00% | 0.997 |
| (13, 6) | 100.00% | 0.821 |
---
## 아키텍처
### 우회 생성 단계
| 버전 | 접근 방식 | PSNR | 워터마크 영향 | 상태 |
|:-------:|:---------|:----:|:----------------:|:------:|
| **V1** | JPEG 압축(Q50) | 37 dB | ~11% 위상 감소 | 기준선 |
| **V2** | 다단계 변환(노이즈, 색상, 주파수) | 27-37 dB | ~0% 신뢰도 감소 | 품질 트레이드오프 |
| **V3** | **다중 해상도 스펙트럼 코드북 차감** | **43+ dB** | **91% 위상 일관성 감소** | 이전 최고 |
| **V4 Round 06** | **7단계 올인원(VAE + 탄성 + 압착 + 색상 + JPEG)** | **시각적 무손실** | **탐지기 우회됨 ✓** | **현재 최고** |
### V3 파이프라인```
Input Image (any resolution)
│
▼
codebook.get_profile(H, W) ──► exact match? ──► FFT-domain subtraction
│ (fast path)
└─ no exact match ──────► spatial-domain resize + subtraction
(fallback path)
│
▼
Multi-pass iterative subtraction (aggressive → moderate → gentle)
│
▼
Anti-alias → Output
Input Image (any resolution) │ ▼ Stage 1: VAE round-trip (SD sd-vae-ft-mse, 1-2 passes) │ Projects image off natural-image manifold ▼ Stage 2: Elastic deformation (smooth random warp field) │ Fragments spatial phase consensus ("collage effect") ▼ Stage 3: Global geometric combo (rotation + zoom + shift) │ Single affine warp, no compounded aliasing ▼ Stage 4: Resize-squeeze (AREA ↓ then LANCZOS ↑) │ Erases sub-pixel watermark information ▼ Stage 5: Color-contrast nudge (HSV micro-shift) │ Shifts per-pixel statistics SynthID keys on ▼ Stage 6: Residual-phase FFT subtraction │ Blog-universal + codebook-harvested carrier bins ▼ Stage 7: JPEG chain + luma noise + bilateral filter │ ▼ Output (SynthID detector: no watermark detected ✓)
---
## 빠른 시작
### 설치```bash
git clone https://github.com/aloshdenny/reverse-SynthID.git
cd reverse-SynthID
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# For Round-06 VAE stage:
pip install torch diffusers safetensors accelerate
import sys sys.path.insert(0, 'src/extraction') from synthid_bypass_v4 import SynthIDBypassV4, SpectralCodebookV4
cb = SpectralCodebookV4() cb.load('artifacts/spectral_codebook_v4.npz')
b = SynthIDBypassV4() result = b.bypass_v4_file( 'input.png', 'output.png', cb, strength='final', # or 'nuke' for maximum strength model='gemini-3.1-flash-image-preview', ) print(result.stages_applied)
### Run V3 Bypass```python
from src.extraction.synthid_bypass import SynthIDBypass, SpectralCodebook
codebook = SpectralCodebook()
codebook.load('artifacts/spectral_codebook_v3.npz')
bypass = SynthIDBypass()
result = bypass.bypass_v3(image_rgb, codebook, strength='aggressive')
print(f"PSNR: {result.psnr:.1f} dB")
print(f"Profile used: {result.details['profile_resolution']}")
CLI에서:```bash
python src/extraction/synthid_bypass.py bypass input.png output.png
--codebook artifacts/spectral_codebook_v3.npz
--strength aggressive
### 워터마크 감지```bash
python src/extraction/robust_extractor.py detect image.png \
--codebook artifacts/codebook/robust_codebook.pkl
reverse-SynthID/ ├── src/ │ ├── extraction/ │ │ ├── synthid_bypass.py # V1/V2/V3 bypass + multi-res SpectralCodebook │ │ ├── synthid_bypass_v4.py # V4 cross-color consensus codebook + dissolver │ │ ├── vae_regen.py # Round-06 SD-VAE re-generation stage │ │ ├── robust_extractor.py # Multi-scale watermark detection (+ V4 hook) │ │ ├── watermark_remover.py # Frequency-domain watermark removal │ │ ├── benchmark_extraction.py # Benchmarking suite │ │ └── synthid_codebook_extractor.py # Legacy codebook extractor │ └── analysis/ │ ├── deep_synthid_analysis.py # FFT / phase analysis scripts │ └── synthid_codebook_finder.py # Carrier frequency discovery │ ├── scripts/ │ ├── download_images.py # Download reference images from HF │ ├── build_codebook_v4.py # V4: build per-(model, HxW) consensus codebook │ ├── dissolve_batch.py # V4: emit strength variants │ └── calibrate_from_feedback.py # V4: update carrier_weights from detection feedback │ ├── artifacts/ │ ├── spectral_codebook_v3.npz # Multi-res V3 codebook [1024x1024, 1536x2816] │ ├── spectral_codebook_v4.npz # V4 codebook (per-model, per-resolution) │ ├── codebook/ # Detection codebooks (.pkl) │ └── visualizations/ # FFT, phase, carrier visualizations │ ├── assets/ │ ├── synthid_watermark.png # Watermark analysis header image │ ├── synthid_white.jpg # Amplified SynthID pattern on white image │ ├── v4_round1_vs_round6.png # Round 01 vs Round 06 fidelity comparison │ └── ... │ ├── runs/ │ ├── round_01/ … round_05/ # Historical bypass attempts │ └── round_06/ # Working bypass (final + nuke presets) │ ├── watermark_investigation/ # Early-stage Nano-150k analysis (archived) └── requirements.txt
---
## 기술 심층 분석
### SynthID 작동 방식 (리버스 엔지니어링)```
┌──────────────────────────────────────────────────────────────┐
│ SynthID Encoder (in Gemini) │
├──────────────────────────────────────────────────────────────┤
│ 1. Select resolution-dependent carrier frequencies │
│ 2. Assign fixed phase values to each carrier │
│ 3. Neural encoder adds learned noise pattern to image │
│ 4. Watermark is imperceptible — spread across spectrum │
├──────────────────────────────────────────────────────────────┤
│ SynthID Decoder (in Google) │
├──────────────────────────────────────────────────────────────┤
│ 1. Extract noise residual (wavelet denoising) │
│ 2. FFT → check phase at known carrier frequencies │
│ 3. If phases match expected values → Watermarked │
└──────────────────────────────────────────────────────────────┘
SynthID의 학습 증강 세트(Gowal et al. 2026, Table 1)에는 SmallRotation, Cropresize, JPEG, GaussianBlur, BrightnessContrast, Screenshotting이 포함되어 있습니다. 이는 모두 전역적이고 균일한 공간 변환입니다. 탄성 워프 필드는 공간적으로 변화하는 왜곡입니다. 각 로컬 이웃은 자체적인 독립적인 서브픽셀 오프셋을 갖습니다. 오프셋이 부드럽기 때문에(백색 잡음에서 가우시안 블러 처리, σ=44–56 px) 이미지 콘텐츠는 시각적으로 영향을 받지 않지만, 워터마크의 위상 일관성 구조는 일관성을 잃어 이미지 전체에 걸쳐 집계할 수 없게 됩니다. 이는 Gemini 자체 앱이 탐지기 실패 모드로 인용하는 '콜라주 조각화' 효과의 픽셀 수준 등가물입니다.
| 메트릭 | 값 |
|---|---|
| PSNR | 43.5 dB |
Alosh Denny AI 워터마킹 연구 · 신호 처리
📧 이메일: [email protected] 🔗 깃허브: https://github.com/aloshdenny
협업, 연구 토론 또는 기여를 원하시면 언제든지 연락하거나 이슈/PR을 생성해 주세요.
이 프로젝트는 독립적으로 유지 관리됩니다 — 연구소 자금이나 기업 후원은 없습니다.
이 작업이 귀하 또는 팀에 유용했다면, 지속적인 개발을 지원해 주시기 바랍니다:
자금은 컴퓨팅 비용(새 해상도 프로필을 위한 GPU 시간), 데이터 세트 확장, 그리고 지속적인 우회 연구에 사용됩니다.
이 프로젝트는 연구 및 교육 목적으로만 사용됩니다. SynthID는 Google DeepMind가 소유한 독점 기술입니다. 이 도구들은 다음을 위해 사용됩니다:
AI가 생성한 콘텐츠를 인간이 만든 것으로 잘못 표현하기 위해 이러한 도구를 사용하지 마십시오.
| Round | 전략 | 결과 |
|---|
| 01 | 보수적 스펙트럼 차감 (온화함) | ✗ |
| 02 | 공격적 스펙트럼 차감 + JPEG | ✗ |
| 03 | 블로그 기반 절대 빈 타겟팅 | ✗ |
| 04 | 잡음 제거 잔차 위상 추출 | ✗ |
| 05 | 확산-VAE 재생성 + 기하 변형 | ✗ |
| 06 | 올인원: VAE + 탄성 분할 + 스퀴즈 + 색상 + JPEG | ✓ |
| V3 | V4 |
|---|
| 참조 색상 | 검정 + 흰색 | 검정, 흰색, 파랑, 초록, 빨강, 회색 (+ 다양한/그라데이션 콘텐츠 기준선) |
| 교차 검증 | abs(cos(phase_black - phase_white)) | 6개 색상에 걸친 교차 색상 합의 + 쌍별 일치 |
| 모델 | 단일 모델(Gemini 2.5) | 모델별 프로필(gemini-3.1-flash-image-preview, nano-banana-pro-preview) + 선택적 union |
| 공격 | 스펙트럼 차감만 | 7단계: VAE + 탄성 + 압착 + 색상 + FFT + JPEG 체인 |
| PSNR(공격적) | 43dB | 시각적 무손실(픽셀 수준 18–24dB; 워프가 픽셀을 이동) |
| 충실도 보호 | 없음 | 단계별 PSNR 하한 롤백 |
| 탐지기 우회 | 로컬만 | Gemini 앱에서 확인됨 ✓ (두 모델 모두) |
| SSIM | 0.997 |
| 캐리어 에너지 감소 | 75.8% |
| 위상 일관성 감소 (상위 5개 캐리어) | 91.4% |
| 모델 | 사전 설정 | 탐지기 우회 |
|---|
| gemini-3.1-flash-image-preview | final | ✓ |
| gemini-3.1-flash-image-preview | nuke | ✓ |
| nano-banana-pro-preview | final | ✓ |
| nano-banana-pro-preview | nuke | ✓ |