AI 워터마킹: 이전 단어에 의해 유도되는 녹색/적색 토큰 편향, z-검정 탐지기, 그리고 패러프레이징이 이를 깨뜨리는 이유
요약
AI 생성 텍스트를 식별하기 위한 워터마킹 기술의 원리와 구현 방식을 설명합니다. 이전 토큰을 기반으로 어휘를 녹색/적색 리스트로 분할하고, 녹색 토큰의 선택 확률을 미세하게 높여 통계적 z-검정으로 탐지하는 메커니즘을 다룹니다.
핵심 포인트
- 이전 토큰의 해시값을 시드로 사용하여 어휘를 녹색/적색 리스트로 분할
- 녹색 리스트 토큰에 미세한 가중치(delta)를 더해 자연스러운 생성 유도
- z-검정을 통해 녹색 토큰의 출현 빈도가 통계적 임계치를 넘는지 확인하여 탐지
- 탐지기는 모델의 가중치 정보 없이도 규칙만으로 작동 가능
제가 계속해서 받는 질문은 "기계에 접근할 수 없는 상태에서, 특정 텍스트가 기계에 의해 작성되었다는 것을 어떻게 증명할 수 있는가?"입니다. AI 워터마킹 (AI watermarking)은 놀라울 정도로 영리한 해답이며, 저는 그 트릭을 이해하고 나자 그것을 믿기 위해 직접 구현해 보아야 했습니다. 생성기 (Generator)는 출력물에 의도적으로 신호를 숨깁니다. 오직 '규칙'만을 알고 있는 탐지기 (Detector)는 (모델이나 가중치에 대한 정보 없이도) 확신에 찬 통계적 판결과 함께 이를 읽어냅니다. 저는 녹색 리스트 시딩 (green-list seeding), 녹색 비율 (green fraction), z-점수 (z-score) 및 p-값 (p-value)이 모두 브라우저에서 실시간으로 계산되는 데모를 구축했습니다. 워터마킹을 켠 상태 또는 끈 상태로 문장을 생성한 다음, 모델을 모르는 탐지기가 이를 판별하도록 해보세요. 작동 방식은 다음과 같습니다 (Kirchenbauer et al., 2023을 따름).
어휘를 녹색 리스트와 적색 리스트로 분할하기
핵심 아이디어는 어휘의 절반을 부드럽게 선호하도록 만드는 것입니다. 매 단계마다, 이전 토큰 (previous token)을 해싱 (hash)하여 의사 난수 생성기 (PRNG)의 시드 (seed)로 사용하고, 이를 통해 어휘를 섞은 뒤 앞쪽 절반을 녹색 리스트 (green list)로 취합니다.
function greenList(prevToken){
const rnd = mulberry32(hashStr(prevToken)); // 이전 단어로부터 시드 생성
const arr = VOCAB.slice();
...
시드가 오직 이전 토큰에만 의존하기 때문에, 작성자와 탐지기는 모든 위치에서 '정확히 동일한' 분할을 계산합니다. 즉, 해싱 규칙 외에 공유해야 할 비밀은 없습니다. 또한 매 단계마다 변경되기 때문에, 이 분할은 눈에 띄지 않으며 쉽게 제거될 수 없습니다.
워터마크는 규칙이 아니라 부드러운 유도입니다
다음 단어를 샘플링 (sampling)하기 전에, 모든 녹색 후보의 점수에 작은 상수 $\delta$를 더한 다음 정상적으로 샘플링합니다.
const scored = candidates.map(w => ({ w, s: baseScore(w) + (green.has(w) ? delta : 0) }));
return softmaxSample(scored); // 여전히 무작위임 — $\delta$는 확률을 기울일 뿐임
결정적으로 이것은 부드럽습니다 (soft). 많은 녹색 단어들이 존재하기 때문에 모델은 실제 선택권을 유지하며 텍스트는 자연스럽게 읽힙니다. 즉, 독자는 아무런 이상함을 느끼지 못합니다. $\delta=0$으로 설정하면 워터마크가 없는 일반적인 텍스트가 생성되며, $\delta$를 높이면 워터마크는 강해지지만 글쓰기는 약간 더 제약됩니다. $\delta$는 탐지 가능성 (detectability)과 품질 (quality) 사이를 조절하는 노브 (knob)입니다.
탐지기는 한 줄짜리 z-검정 (z-test) 입니다
사람이 쓰는 글은 어떤 단어가 녹색인지 알지 못하므로, 순전히 우연에 의해 각 단어가 녹색일 확률은 약 50%입니다. 워터마크가 삽입된 모델은 이 수치를 훨씬 상회합니다. 따라서 탐지기는 텍스트를 이해할 필요가 없으며, 단지 개수를 세기만 하면 됩니다:
const T = scoredTokens, green = greenCount;
const z = (green - 0.5*T) / Math.sqrt(T * 0.5 * 0.5); // 전체 테스트
// human: green ≈ 0.5·T → z ≈ 0 → "human"
...
$z$-점수 ($z$-score)는 실제 녹색 단어의 개수가 예상되는 개수보다 표준 편차의 몇 배만큼 위에 있는지를 측정합니다. $z > 4$라는 임계값 (threshold)은 약 30,000분의 1 정도의 오탐률 (false-alarm rate)을 제공합니다. $z$는 $\sqrt{T}$에 비례하여 증가하기 때문에, 지문이 길수록 판별하기가 훨씬 쉽습니다. 트윗은 워터마크가 찍혀 있더라도 너무 짧을 수 있지만, 에세이는 매우 쉽습니다. 데모에서는 어떤 단어든 클릭하여 이전 단어가 생성한 정확한 녹색/적색 분할을 확인할 수 있으며, 개수와 판결이 업데이트되는 것을 볼 수 있습니다.
패러프레이징 (paraphrasing)이 이를 깨뜨리는 이유
신호는 토큰 (token)의 정확한 사슬 속에 존재하며, 이로 인해 신호는 실재하지만 취약합니다. 단어를 유의어로 바꾸면 해당 단어뿐만 아니라 다음 단어가 판단되는 기준이 되는 녹색 목록 (green list) 자체가 바뀌게 됩니다. 따라서 녹색 목록을 무시하고 다시 쓰는 작업은 녹색 비율을 다시 50%에 가깝게 끌어내리고 $z$-점수를 임계값 아래로 떨어뜨립니다. 데모의 "패러프레이즈 공격 (paraphrase attack)"은 정확히 이 작업을 수행합니다. 즉, 판결이 "AI가 작성함 (AI-written)"에서 "사람처럼 보임 (looks human)"으로 붕괴됩니다. 기계 번역을 통한 왕복 번역 (round-trips)이나 대대적인 인간의 편집도 동일한 결과를 초래합니다. 공짜 점심은 없습니다. 강건성 (robustness), 품질 (quality), 그리고 탐지 가능성 (detectability)은 서로 트레이드오프 (trade-off) 관계에 있습니다.
이미지도 유사한 방식으로 작동합니다
이미지에는 어휘 (vocabulary)가 없으므로, 생성기 (generators)는 픽셀에 희미한 비밀 $\pm 1$ 패턴을 임베딩 (embed)하고 동일한 키 (key)와 상관관계 (correlating)를 분석하여 이를 탐지합니다. 워터마크가 삽입된 이미지는 높은 점수를 기록하고, 깨끗한 이미지는 $\approx 0$의 점수를 기록합니다. Google의 SynthID는 신경망 (neural) 버전을 사용하여 제가 만든 장난감 모델보다 자르기 (crops) 및 압축 (compression)에 훨씬 더 잘 견디도록 설계되었지만, 그 논리는 동일하며 과도한 편집은 여전히 워터마크를 약화시킵니다. 워터마킹은 사후 탐지기 (post-hoc detectors) 및 콘텐츠 자격 증명 (content credentials)과 함께 출처 (provenance)를 증명하는 하나의 계층이며, 진정으로 유용하지만 완벽하지는 않습니다.
직접 구절을 생성하고, 워터마크를 뒤집은 뒤, 패러프레이징 공격 (paraphrase attack)을 실행해 보세요:
https://dev48v.infy.uk/ai/days/day46-ai-watermarking.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기