파일 개요
nsfw_api_browser.js는 T2Editor(9.1.0)의 기본 브라우저 NSFW 추론 엔진입니다.
이 파일은 이미지 플러그인에서 동적으로 불러와지며, 업로드 전 이미지 파일을 검사해 결과를 기존 UI에 전달합니다. 중요한 점은 이 파일이 자체 UI를 그리지 않는다는 것입니다. 경고 배지, 경고 모달, 상태바는 plugin/image/image.js와 plugin/image/image.css가 담당하고, nsfw_api_browser.js는 오직 모델 로딩, 백엔드 선택, 분류 결과 반환에 집중합니다.
초보자와 웹마스터를 위한 이해
이 파일은 “이미지를 업로드하기 전에 브라우저 안에서 NSFW 여부를 먼저 검사하는 엔진”입니다.
예전에는 브라우저 쪽 코드 안에 자체 worker/CNN 로직이 들어 있었고, 경우에 따라 서버에서 모델을 받아오는 흐름도 섞여 있었습니다. 업그레이드 후에는 구조가 더 단순해졌습니다.
지금 방식
- 브라우저가
tfjs와nsfwjs를 자체 호스팅 경로에서 읽음 - 기본 모델은
MobileNetV2Mid - 가능하면
WebGPU를 먼저 사용 - 안 되면
webgl,wasm,cpu순으로 자동 폴백 - 결과만 기존 이미지 UI에 전달
즉, 이 파일은 판정 엔진이고, 화면에 보이는 배지나 팝업은 다른 파일이 맡습니다.
이번 업그레이드에서 바뀐 핵심
기존 구조
- 자체
Worker생성 - 긴 인라인 CNN/GradCAM 구현 포함
_handleWorkerMessage,_processImageElement,destroy중심 구조- 브라우저 모드에서도 서버
?action=get_model의존 가능
변경 후 구조
- 자체 CNN/worker 제거
nsfwjs v2사용- 기본 모델을
MobileNetV2Mid로 고정 가능 - 모델과 런타임을
/vendor기준 자체 호스팅 가능 webgpu -> webgl -> wasm -> cpu순 백엔드 선택- 결과 포맷을
safe / suspect / unsafe / error중심으로 정리 - 자체 UI 없이 기존 이미지 플러그인 UI에만 결과 공급
한 문장으로 요약하면,
기존 브라우저 NSFW 코어를 직접 구현형 worker 엔진에서, 자체 호스팅 가능한 nsfwjs 기반 엔진으로 교체한 파일입니다.
초보자 관점에서 알아둘 점
이 파일을 수정해야 하는 경우는 흔하지 않습니다.
보통은 아래만 관리하면 충분합니다.
- 모델 파일이
/vendor/nsfwjs/models/...아래에 있는지 tfjs,nsfwjs스크립트가 404 없이 열리는지- 브라우저가 WebGPU를 지원하지 않아도 폴백이 정상 동작하는지
오류가 나면 보통 세 가지를 먼저 봅니다.
- 정적 파일 경로가 맞는지
- 브라우저에서
navigator.gpu를 지원하는지 wasm바이너리 경로가 맞는지
전문 개발자를 위한 분석
주요 책임
- 파일 이름:
nsfw_api_browser.js - 파일 위치:
9.1.0/t2editor/config/nsfw_api_browser.js - 주요 역할:
- TensorFlow.js 런타임 스크립트 로딩
- 선택적 백엔드(WebGPU/WebGL/WASM) 등록
- NSFWJS 모델 로딩
- 입력 이미지 정규화
- 분류 결과를 T2Editor 공용 포맷으로 반환
실제 클래스 구조
이 파일의 중심은 NSFWFilterAPI 클래스입니다.
주요 메서드는 아래와 같습니다.
load()
런타임과 모델을 실제로 올립니다.
tfjs로드- 선택한 백엔드 스크립트 로드
tf.ready()대기- 우선순위에 따라 백엔드 선택
nsfwjs.load()로 모델 로드
즉, 이 메서드는 “엔진 준비 완료”까지 담당합니다.
_registerOptionalBackends(tf, assets)
설정된 우선순위에 따라 필요한 백엔드 스크립트를 조건부로 불러옵니다.
webgpu:navigator.gpu지원 시만 시도webgl: 브라우저 가속 후보wasm: 정적 바이너리 경로 지정 가능
이 메서드는 사용 가능한 백엔드를 미리 등록하는 단계입니다.
_selectBackend(tf)
백엔드를 실제로 전환합니다.
기본 우선순위는 아래와 같습니다.
textwebgpu -> webgl -> wasm -> cpu
후보마다 tf.setBackend()를 시도하고, 실패하면 다음 후보로 넘어갑니다.
classify(input, heatmap = false)
실제 분류 진입점입니다.
- 입력을 이미지 요소 또는 Blob/File 등에서 정규화
this._model.classify()호출- 예측 배열을 T2Editor용 결과 포맷으로 변환
반환 결과는 단순 boolean이 아니라 다음 정보를 포함합니다.
labelprobconfidencebackendexplicitScorensfwScoresexyScoresafeScoretopPredictionpredictions
classifyWithHeatmap(input)
기존 호출부 호환을 위해 남겨둔 래퍼입니다. 현재 구현은 heatmap을 별도로 만들지 않고 classify()로 위임합니다.
dispose()
로드된 모델을 해제합니다.
이 메서드는 예전의 destroy()를 대체하는 성격으로 보면 됩니다.
기존 함수와 현재 함수의 대응
| 기존 구조 | 현재 구조 |
|---|---|
_handleWorkerMessage() | 제거됨. worker 기반 구조 자체 제거 |
_processImageElement() | _normalizeInput()으로 역할 재구성 |
destroy() | dispose()로 대체 |
| 인라인 CNN/GradCAM | nsfwjs + tfjs 사용 |
결과 포맷과 판정 규칙
현재 결과는 단순 unsafe/safe 이분법이 아니라 아래처럼 확장됩니다.
safesuspectunsafeerror
내부적으로는 예측 클래스(porn, hentai, sexy, neutral, drawing)를 다시 조합해 다음 점수를 계산합니다.
explicitScorensfwScoresafeScore
그리고 임계치를 기준으로 최종 라벨을 정합니다.
이 설계 덕분에 이미지 UI는 “차단/허용”만이 아니라, 의심 상태를 배지와 경고 모달로 표현할 수 있습니다.
호출 관계
현재 흐름은 아래처럼 이해하면 됩니다.
editor.lib.php가 전역 NSFW 설정값 주입plugin/image/image.js가import(window.T2EDITOR_NSFW_BROWSER_URL)실행image.js가new NSFWFilterAPI(...)생성nsfw_api_browser.js가 런타임/모델을 로드classify(file)실행- 결과를 이미지 미리보기 배지와 경고 로직에 전달
즉, 이 파일은 엔진, image.js는 업무 흐름과 UI, image.css는 표현 계층입니다.
수정 시 영향 및 안전 지침
특히 조심해야 하는 부분
assets경로 형식modelUrl과modelType의 조합backendPriority순서- 반환 결과의 필드 이름
이 네 가지를 바꾸면 image.js 쪽과 바로 연결이 깨질 수 있습니다.
안전하게 수정하는 방법
- 결과 포맷 키(
label,prob,backend,predictions)는 유지 dispose()이름 유지classifyWithHeatmap()는 바로 제거하지 말고 호환 래퍼로 남기기webgpu실패를 오류로 보지 말고 폴백으로 처리- 정적 자산 경로를 바꿀 때는
/vendor전체 경로를 함께 검증
테스트 포인트
필수 테스트
- WebGPU 지원 브라우저에서
backend = webgpu확인 - WebGPU 미지원 브라우저에서
webgl또는wasm폴백 확인 - 모든 자산이 404 없이 로드되는지 확인
safe/suspect/unsafe/error가 UI에 올바르게 매핑되는지 확인- 다중 이미지 업로드에서 캐시/중복 로딩 문제가 없는지 확인
장애 시 흔한 원인
vendor/정적 파일 누락model.json경로 오설정tfjs-backend-wasm바이너리 경로 누락nsfwjs.min.js로드 실패- 결과 포맷 변경으로 인한
image.js해석 실패
관련 파일과 함께 봐야 하는 곳
editor.lib.phpplugin/image/image.jsplugin/image/image.css- 필요 시
config/nsfw_api_server.php(레거시 fallback)
문서 유지보수 메모
기존 9.0.0 문서에 있던 아래 설명은 더 이상 맞지 않습니다.
- “시스템 초기화, 플러그인 로딩, 이벤트 처리 등 에디터 동작의 핵심 부분”
- “
_handleWorkerMessage,_processImageElement,destroy가 현재 주요 메서드”
현행 문서 기준 설명은 아래 문장으로 대체합니다.
nsfw_api_browser.js는 nsfwjs v2 MobileNetV2Mid와 TensorFlow.js를 이용해 브라우저 안에서 NSFW 판정을 수행하고, 그 결과만 기존 이미지 플러그인 UI에 전달하는 코어 엔진 파일입니다.