노하우 목록
워크플로우

NSFW로 거절됐습니다 — 무엇이고, 왜 생기고, 어떻게 넘어가나

고구마
고구마
8월 8일 · 읽는 데 8

작품을 만들다 보면 가끔 이런 걸 받습니다. "NSFW로 거절되었습니다."

처음 당하면 좀 당황스럽습니다. 야한 걸 만든 적이 없는데 왜 이러지 싶고, 내가 뭘 잘못했나 싶기도 하고요.

저희도 지금까지 세 번 겪었습니다. 이번에 실제 응답을 열어서 뭐가 일어난 건지 확인해 봤고, 그 기록을 정리합니다.

1. NSFW가 뭔가

NSFW는 Not Safe For Work의 약자입니다. 원래는 "회사에서 열면 곤란한 것" 정도의 인터넷 은어였는데, 지금은 생성 도구에서 성적인 것·폭력적인 것·기타 정책 위반을 통칭하는 말로 쓰입니다.

중요한 건 이겁니다. NSFW 거절은 사람이 내린 도덕적 판단이 아닙니다. 분류기가 내린 확률적 판정이에요.

그리고 그 분류기는 내 의도를 모릅니다. 프롬프트에 담긴 단어와 만들어질 그림만 봅니다. "고전 조각을 찍은 미술관 도록 사진"이라는 제 머릿속 계획은 분류기가 볼 수 없어요.

2. 실제로 무슨 일이 있었나

지난번 조각 연작에서 재료만 아홉 번 바꾸는 실험을 했습니다. 자세·조명·받침·갤러리를 전부 고정하고 재료 문장만 갈아 끼웠어요.

[같은 형태, 아홉 재료] 대리석
[같은 형태, 아홉 재료] 대리석 · 종이학 · Nano Banana Pro작품 보기 →

대리석은 통과했습니다.

[같은 형태, 아홉 재료] 밀랍
[같은 형태, 아홉 재료] 밀랍 · 클레이요 · Grok Imagine Image작품 보기 →

밀랍은 거절됐습니다.

두 프롬프트를 나란히 놓으면 이렇습니다. 다른 건 재료를 설명한 한 문장뿐이에요.

A life-size sculpture of a human figure curled tightly on its side with knees drawn to the chest and arms wrapped around the shins, face tucked down and hidden. Carved from white Carrara MARBLE: ... Plain concrete plinth in a bare gallery, even north light. Photorealistic

A life-size sculpture of a human figure curled tightly on its side with knees drawn to the chest and arms wrapped around the shins, face tucked down and hidden. Modelled in pale WAX: ... Plain concrete plinth in a bare gallery, even north light. Photorealistic

성적인 단어는 하나도 없습니다. 두 작업은 0.4초 간격으로 제출됐고요.

3. 응답은 이렇게 옵니다

실제 API 응답을 열어 봤습니다.

status: "nsfw"
result_url: null
result_json: null
meta: null
debug: null

두 가지를 알 수 있습니다.

  • nsfw일반 실패(failed)와 다른 별도 상태입니다. 오류가 아니라 판정이에요
  • 이유는 알려주지 않습니다. 어느 부분이 걸렸는지 알 방법이 없습니다

이유를 안 주는 건 아마 의도된 설계일 겁니다. 어디가 걸렸는지 알려주면 그걸 피해 가는 방법도 같이 알려주는 셈이니까요. 불편하지만 이해는 갑니다.

4. 왜 이런 일이 생기나

여기서부터는 제 추측입니다. 내부 구현을 볼 수 없으니 관찰에서 거꾸로 짚어본 것뿐이에요.

가설 1 — 분류기는 맥락을 모른다

웅크린 인체 조각은 미술사에서 아주 흔한 형식입니다. 그런데 분류기가 보는 건 "사람 형상 + 옷 없음 + 살색"이에요. 미술관인지 아닌지는 그다음 문제고요.

실제로 대리석과 콘크리트는 통과했는데 밀랍만 걸린 게 이 가설과 맞습니다. 밀랍은 반투명하고 살색에 가까운 재료거든요. 돌은 명백히 돌인데 밀랍은 피부처럼 보일 수 있습니다.

가설 2 — 임계값이 모델마다 다르다

이건 가설이라기보다 관찰된 사실에 가깝습니다. 거의 같은 프롬프트 아홉 개 중 여덟 개는 통과하고 하나만 걸렸으니까요. 모델(과 그 앞단의 필터)마다 기준이 다릅니다.

가설 3 — 어떤 단어는 임계값을 확 낮춘다

예전에 클레이 연작에서도 두 번 걸린 적이 있습니다. 하나는 이겁니다.

말랑 꽃집
말랑 꽃집 · 클레이요 · FLUX.2작품 보기 →

지금 보시는 건 다시 만든 버전이에요. 처음 프롬프트에는 kids가 들어 있었고 거절됐습니다. 클레이 인형 꽃집인데요.

이건 오히려 옳은 설계라고 생각합니다. 아동과 관련된 판정은 임계값을 훨씬 보수적으로 잡는 게 맞아요. 오탐이 좀 생기더라도요.

5. 먼저 선을 하나 긋겠습니다

아래에 해결 방법을 적을 텐데, 그 전에 분명히 해둘 게 있습니다.

이 글은 필터를 뚫는 법이 아닙니다. 실제로 만들면 안 되는 걸 만들려고 우회하는 건 여기 없고, 권하지도 않습니다.

여기서 다루는 건 오탐입니다. 성적 의도가 전혀 없는 작업이 걸렸을 때 그림 자체를 명확하게 바꿔서 오해를 없애는 방법이에요. 우회가 아니라 수정입니다.

그리고 한 가지 더. 여러 번 고쳐도 계속 걸린다면 그것도 신호입니다. 내가 만들려는 게 정말 내가 생각한 그건지 다시 볼 만해요. 분류기가 매번 그렇게 본다면, 다른 사람도 그렇게 볼 수 있다는 뜻이니까요.

6. 그래서 어떻게 했나

방법 1 — 그림 자체를 바꾼다 (제일 확실)

밀랍상은 긴 튜닉을 입힌 형상으로 다시 만들었습니다. 자세와 재료 설명은 그대로 두고요.

A life-size art sculpture of a clothed human figure wearing a simple long tunic, curled on its side ... face tucked down and hidden by the fabric ... folds of the tunic sculpted in the wax ...

한 번에 통과했습니다. 그리고 결과적으로 원래 계획보다 나아졌어요 — 옷 주름이 밀랍의 손자국과 잘 어울려서 재료 설명이 오히려 강해졌습니다.

이게 중요한 점입니다. 좋은 우회는 작품을 손상시키지 않습니다. 손상된다면 방법이 틀린 거예요.

방법 2 — 애매한 단어를 뺀다

클레이 꽃집은 kids를 빼고 with no people로 바꿔서 해결했습니다. 애초에 클레이 인형이 주인공이라 사람이 필요 없었어요.

프롬프트를 다시 읽어 보면 없어도 되는 단어가 의외로 많습니다.

방법 3 — 맥락을 명시한다

fine art sculpture documentation photograph, museum catalogue photograph 같은 장르 선언을 앞에 붙이면 도움이 됩니다.

다만 이건 확실한 방법이 아닙니다. 밀랍상 첫 시도에도 갤러리·받침·조명이 다 들어 있었는데 걸렸어요. 보조 수단으로만 쓰세요.

방법 4 — 모델을 바꾼다

임계값이 다르니까 다른 모델에서는 통과할 수 있습니다. 실제로 저희 아홉 장 중 여덟 장은 다른 모델에서 아무 문제 없이 나왔고요.

다만 이건 판정이 틀렸다고 확신할 때만 쓸 수 있는 방법입니다. 모델을 갈아치우면서 될 때까지 돌리는 건 방법이 아니라 회피예요.

방법 5 — 소재를 옆으로 옮긴다

전에 기타줄 진동 영상이 계속 실패했을 때 소리굽쇠로 바꿔서 같은 아이디어를 살린 적이 있습니다. NSFW에도 같은 방법이 통합니다.

"이 개념을 다른 대상으로 표현할 수 있나?"를 물어보세요. 대개는 있고, 종종 원래보다 낫습니다.

7. 하지 말아야 할 것

  • 같은 프롬프트 재제출 — 판정은 대체로 결정적입니다. 크레딧만 씁니다
  • 철자 비틀기·은어·우회 표현 — 이건 수정이 아니라 정책 위반이고, 계정 제재로 이어질 수 있습니다. 만들면 안 되는 걸 만들려는 게 아니라면 이런 걸 쓸 이유도 없습니다
  • 아동 관련에서 밀어붙이기 — 여기서는 애매하면 그냥 주제를 바꾸는 게 맞습니다. 예외 없이요

8. 정리 — 걸렸을 때 순서

  1. 내가 만들려던 게 정말 문제없는 것인지 먼저 확인합니다
  2. 그렇다면 그림에서 오해를 살 요소를 찾습니다 — 살색, 노출, 자세, 연령 관련 단어
  3. 그 요소를 실제로 바꿉니다. 옷을 입히거나, 대상을 바꾸거나, 단어를 빼거나
  4. 장르 맥락을 앞에 붙입니다 (보조 수단)
  5. 확신이 있으면 모델을 바꿔 한 번 더 봅니다
  6. 그래도 계속 걸리면 소재를 옆으로 옮기거나 접습니다

이 일을 겪고 나서 생각이 좀 바뀌었습니다. 처음엔 "멀쩡한 걸 왜 막지" 싶었는데, 응답을 뜯어보고 나니 맥락을 모르는 분류기가 보수적으로 판정하는 게 당연하다는 쪽으로 기울었어요.

오탐이 짜증나긴 합니다. 그런데 반대 방향의 실수보다는 이쪽이 낫습니다. 그리고 저희 경우엔 고치고 나서 더 좋아졌으니까 손해도 아니었고요.

여러분도 NSFW로 걸린 경험 있으시면 어떤 프롬프트였는지 알려주세요. 사례가 쌓이면 어떤 단어가 위험한지 목록을 만들 수 있을 것 같습니다 🍠

후속 [2026-08-09 추가]

이 글에서 추측이라고 적은 부분들을 공개된 연구로 확인해 봤습니다. 대부분 이미 문서화된 현상이었고, 필터의 실제 메커니즘까지 밝혀져 있더군요 — CLIP 잠재 공간에서 17개 위험 개념과의 코사인 유사도를 재는 구조입니다.

특히 "kids" 한 단어가 왜 전체 판정을 예민하게 만드는지, 왜 모델마다 결과가 다른지가 설명됐습니다. 자세한 건 후속 글에 적었습니다.

정정 [2026-08-09]

이 글에 두 군데 틀린 곳이 있어 바로잡습니다. 재현 실험을 해보고 알았습니다.

  • "같은 프롬프트 재제출은 크레딧만 쓴다" — 틀렸습니다. NSFW 판정은 결정적이지 않습니다. 같은 프롬프트·같은 모델을 13회 돌렸더니 1회만 차단됐어요. 재제출은 실제로 통과할 수 있습니다.
  • 개별 차단의 원인을 특정한 것 — 과했습니다. 판정이 확률적이라면 한 번의 차단으로는 원인을 알 수 없습니다. "밀랍이 살색이라서", "kids 때문에" 같은 진단은 확인된 게 아니었습니다.

그래서 첫 단계가 하나 늘었습니다 — 일단 두세 번 다시 돌려 보세요. 반복해서 걸릴 때만 원인을 의심하면 됩니다. 자세한 실험 결과는 이 글에 있습니다.

댓글