🔐로그인하면 문서 작성, 프로젝트 게시, ZIP 기반 버전 업로드, 브랜치 생성 기능을 사용할 수 있습니다. 로그인하러 가기

가이드: NSFWJS 커스텀 모델 설치와 적용

Answer Summary

--- title: 가이드: NSFWJS 커스텀 모델 설치와 적용 document_id: guide-nsfwjs-custom-model-installation slug: guide-nsfwjs-custom-model-installation target_editor_version: 9.1.0 document_type: gu…

브랜치 ⎇ main
리비전 r2
작성자 T2Editor
수정 2026.04.17
요약 고아링크 삭제
md

#가이드 #NSFWJS

요약

이 문서는 T2Editor 9.1.0에서 기본 제공 모델 외의 버전을 붙이는 절차를 설명합니다. 여기서 말하는 “다른 버전”은 다음을 모두 포함합니다.

  • nsfwjs가 기본으로 제공하는 다른 번들 모델 사용
  • 동일 계열 모델을 직접 호스팅한 URL로 사용
  • TFJS로 변환한 커스텀 model.json 사용

문서 목적

T2Editor 9.1.0의 브라우저 NSFW 필터는 nsfw_api_browser.js 래퍼를 통해 모델을 로드합니다. 이 래퍼는 T2_NSFW_BROWSER_MODEL_URL이 설정되어 있으면 그 URL을 우선 사용하고, 없으면 T2_NSFW_BROWSER_MODEL 값을 사용합니다.

따라서 기본 MobileNetV2Mid 대신 다른 모델을 쓰고 싶다면, 실제 변경 포인트는 대부분 editor.lib.php의 전역 설정과 vendor/nsfwjs/models/... 경로 정리입니다.

초보자와 웹마스터용 한 줄 이해

  • 가장 안전한 방법: 기본 구조는 유지하고 model.json 경로만 바꿉니다.
  • 가장 자주 나는 문제: 경로 오타, type: 'graph' 누락, 입력 크기 불일치입니다.
  • 가장 중요한 점: T2Editor의 현재 판정 로직은 Drawing / Hentai / Neutral / Porn / Sexy 클래스를 기대합니다. 클래스 이름이나 개수가 달라지면 로딩은 되어도 판정 의미가 깨질 수 있습니다.

지원 시나리오

1. 기본 번들 모델 이름만 바꾸기

nsfwjs는 기본적으로 MobileNetV2, MobileNetV2Mid, InceptionV3 세 가지 번들 모델 이름을 지원합니다.

이 경우 T2_NSFW_BROWSER_MODEL_URL 없이 T2_NSFW_BROWSER_MODEL만 바꿔도 됩니다.

php
if (!defined('T2_NSFW_BROWSER_MODEL')) define('T2_NSFW_BROWSER_MODEL', 'InceptionV3'); if (!defined('T2_NSFW_BROWSER_MODEL_URL')) define('T2_NSFW_BROWSER_MODEL_URL', null); if (!defined('T2_NSFW_BROWSER_MODEL_TYPE')) define('T2_NSFW_BROWSER_MODEL_TYPE', null);

InceptionV3는 299x299 입력을 쓰는 모델 계열이라, 상대적으로 더 무겁고 느릴 수 있습니다. 운영 환경에서는 먼저 테스트 환경에서 로딩 시간과 분류 시간을 확인하세요.

2. 기본 제공 모델을 자체 호스팅 URL로 바꾸기

가장 권장되는 방식입니다. 예를 들어 mobilenet_v2_mid를 CDN이 아니라 로컬 정적 경로에서 읽게 바꿀 수 있습니다.

php
if (!defined('T2_NSFW_BROWSER_MODEL')) define('T2_NSFW_BROWSER_MODEL', 'MobileNetV2Mid'); if (!defined('T2_NSFW_BROWSER_MODEL_URL')) define( 'T2_NSFW_BROWSER_MODEL_URL', T2_NSFW_RUNTIME_ASSET_BASE . '/nsfwjs/models/mobilenet_v2_mid/model.json' ); if (!defined('T2_NSFW_BROWSER_MODEL_TYPE')) define('T2_NSFW_BROWSER_MODEL_TYPE', 'graph');

이 방식은 현재 T2Editor 9.1.0 수정본의 기본 구조와 가장 잘 맞습니다.

3. 직접 변환한 커스텀 TFJS 모델 붙이기

TensorFlow 또는 Keras 모델을 TFJS 형식으로 변환해서 model.json + weight 파일들 형태로 두고, 그 URL을 T2_NSFW_BROWSER_MODEL_URL에 넣는 방식입니다.

php
if (!defined('T2_NSFW_BROWSER_MODEL_URL')) define( 'T2_NSFW_BROWSER_MODEL_URL', T2_NSFW_RUNTIME_ASSET_BASE . '/nsfwjs/models/custom_nsfw_v1/model.json' ); if (!defined('T2_NSFW_BROWSER_MODEL_TYPE')) define('T2_NSFW_BROWSER_MODEL_TYPE', 'graph');
주의

커스텀 모델이라고 해서 모두 드롭인 대체가 가능한 것은 아닙니다. 현재 T2Editor 9.1.0의 판정 로직은 Porn, Hentai, Sexy, Neutral, Drawing 확률을 읽어 safe / suspect / unsafe를 계산합니다. 따라서 출력 클래스 체계가 다르면 추가 코드 수정이 필요합니다.

설치 절차

1단계. 모델 폴더 준비

예시 경로:

text
/var/www/html/plugin/editor/t2editor/vendor/nsfwjs/models/custom_nsfw_v1/ model.json group1-shard1ofN.bin group1-shard2ofN.bin

2단계. 웹에서 직접 열리는지 확인

bash
curl -I http://127.0.0.1/plugin/editor/t2editor/vendor/nsfwjs/models/custom_nsfw_v1/model.json

응답이 200 OK여야 합니다.

3단계. editor.lib.php 설정 변경

php
if (!defined('T2EDITOR_URL')) define('T2EDITOR_URL', '/plugin/editor/t2editor'); if (!defined('T2_NSFW_RUNTIME_ASSET_BASE')) define('T2_NSFW_RUNTIME_ASSET_BASE', T2EDITOR_URL . '/vendor'); if (!defined('T2_NSFW_BROWSER_MODEL')) define('T2_NSFW_BROWSER_MODEL', 'CustomNSFW'); if (!defined('T2_NSFW_BROWSER_MODEL_URL')) define( 'T2_NSFW_BROWSER_MODEL_URL', T2_NSFW_RUNTIME_ASSET_BASE . '/nsfwjs/models/custom_nsfw_v1/model.json' ); if (!defined('T2_NSFW_BROWSER_MODEL_TYPE')) define('T2_NSFW_BROWSER_MODEL_TYPE', 'graph');

4단계. 브라우저에서 실제 로딩 확인

개발자 도구 Network 탭에서 다음을 확인합니다.

항목기대 결과실패 시 의심점
tf.min.js200vendor 경로 오류
tf-backend-webgpu.min.js200 또는 미사용백엔드 파일 없음
nsfwjs.min.js200vendor 경로 오류
model.json200URL 오타, 권한 문제
*.bin200model.json 내부 weightsManifest 경로 문제

어떤 모델 타입을 써야 하나

현재 T2Editor 9.1.0 래퍼는 URL 기반 모델을 읽을 때 T2_NSFW_BROWSER_MODEL_TYPE을 nsfwjs load() 옵션으로 넘깁니다.

모델 계열권장 type추가 옵션비고
MobileNetV2생략 가능필요 시 size: 224가벼운 편
MobileNetV2Midgraph별도 size 없음현재 기본 권장값
InceptionV3생략 가능size: 299더 무거울 수 있음
직접 변환한 GraphModelgraph모델에 따라 다름TF SavedModel/Hub 변환 계열에 자주 해당
직접 변환한 LayersModelnull입력 크기 점검 필요Keras 기반 TFJS 변환 계열에서 자주 사용
노트

문서상 MobileNetV2Mid는 graph 모델로 로드해야 할 수 있다고 안내되어 있습니다. 현재 T2Editor 9.1.0 기본값도 이 안내에 맞춰 graph를 사용합니다.

모델을 바꿀 때 같이 봐야 하는 항목

입력 크기

nsfwjs 문서 기준으로 MobileNetV2는 224x224, InceptionV3는 299x299를 사용합니다. 커스텀 모델도 자기 입력 크기에 맞는 설정이 필요할 수 있습니다.

현재 T2Editor 9.1.0의 브라우저 래퍼는 type은 전달하지만 size를 별도 전역 설정으로 노출하지는 않습니다. 따라서 299 입력이 필요한 모델을 안정적으로 쓰려면 래퍼 확장도 검토해야 합니다.

출력 클래스

T2Editor 9.1.0 판정 로직은 다음 클래스명을 소문자 기준으로 읽습니다.

  • porn
  • hentai
  • sexy
  • neutral
  • drawing

이 다섯 개가 유지되면 현재 UI와 바로 연결됩니다.

threshold 재조정

모델을 바꾸면 확률 분포가 달라질 수 있습니다. 그 경우 아래 임계값을 다시 조정해야 오탐/미탐을 줄일 수 있습니다.

js
unsafeExplicit unsafeCombined suspectExplicit suspectCombined suspectSexy

추천 운영 방식

가장 안전한 운영

  1. MobileNetV2Mid 유지
  2. 자체 호스팅 model.json 사용
  3. graph 유지
  4. webgpu -> webgl -> wasm -> cpu 폴백 유지

실험용 운영

  1. 별도 폴더에 새 모델 설치
  2. 스테이징에서 T2_NSFW_BROWSER_MODEL_URL만 변경
  3. 샘플 이미지 세트로 결과 비교
  4. 문제가 없을 때 운영 반영
샘플 비교 체크리스트
  • 일반 사진 20장
  • 애니/드로잉 20장
  • 경계 사례 20장
  • 실제 차단이 필요한 사례 20장
  • 저해상도/크롭 이미지 20장

자주 생기는 오류

model.json은 열리는데 분류가 안 되는 경우

가능성:

  • T2_NSFW_BROWSER_MODEL_TYPE이 잘못됨
  • model.json 내부 weight shard 경로가 틀림
  • 출력 클래스 체계가 현재 판정 코드와 다름

WebGPU는 되는데 결과가 불안정해 보이는 경우

가능성:

  • 브라우저/드라이버 차이
  • WebGPU 초기화 실패 후 다른 백엔드로 폴백
  • 새 모델의 threshold 미조정

InceptionV3로 바꿨더니 느려진 경우

정상일 수 있습니다. 입력 크기와 모델 크기가 더 커서 로딩/추론 시간이 늘어날 수 있습니다.

개발자를 위한 메모

현재 9.1.0 구현에서 드롭인 대체가 깔끔하게 되는 경우는 같은 5개 클래스 체계를 유지하는 모델입니다. 완전히 다른 데이터셋으로 학습한 모델이나 멀티헤드 출력 모델을 붙이는 경우, buildAssessment() 로직과 UI 메시지 체계를 같이 수정해야 합니다.

또한 URL 기반 모델에서 size 옵션까지 안정적으로 다루려면, 차기 버전에서 예를 들어 아래 같은 설정 추가를 검토할 수 있습니다.

php
T2_NSFW_BROWSER_MODEL_SIZE

수정 요약

  • 기본 제공 모델 외의 버전을 붙이는 절차를 별도 문서로 분리했습니다.
  • URL 기반 모델, graph/layers 타입, 출력 클래스 호환 조건을 문서화했습니다.
이 문서가 링크하는 문서 · 0
아직 내부 링크가 없습니다. 본문에 [[다른-문서]]를 넣으면 연결이 생깁니다.
백링크 · 0
아직 이 문서를 가리키는 다른 문서가 없습니다.
관련 문서
직접 연결된 관련 문서가 아직 없습니다.
문서 연결 지도

이 문서를 중심으로 들어오는 링크와 나가는 링크를 한 번에 볼 수 있습니다.

전체 보기
현재 문서 백링크 나가는 링크 양방향 연결
이 브랜치의 리비전
T2WIKI · 기술 통합 위키 & 프로젝트 허브 · 나무위키 + Markdown 완벽 지원 · SQLite · PHP 8.2 · 소개 · 문법 안내