- 문서 목적
- 초보자와 웹마스터용 한 줄 이해
- 지원 시나리오
- 1. 기본 번들 모델 이름만 바꾸기
- 2. 기본 제공 모델을 자체 호스팅 URL로 바꾸기
- 3. 직접 변환한 커스텀 TFJS 모델 붙이기
- 설치 절차
- 1단계. 모델 폴더 준비
- 2단계. 웹에서 직접 열리는지 확인
- 3단계. editor.lib.php 설정 변경
- 4단계. 브라우저에서 실제 로딩 확인
- 어떤 모델 타입을 써야 하나
- 모델을 바꿀 때 같이 봐야 하는 항목
- 입력 크기
- 출력 클래스
- threshold 재조정
- 추천 운영 방식
- 가장 안전한 운영
- 실험용 운영
- 자주 생기는 오류
- model.json은 열리는데 분류가 안 되는 경우
- WebGPU는 되는데 결과가 불안정해 보이는 경우
- InceptionV3로 바꿨더니 느려진 경우
- 개발자를 위한 메모
- 수정 요약
이 문서는 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만 바꿔도 됩니다.
phpif (!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이 아니라 로컬 정적 경로에서 읽게 바꿀 수 있습니다.
phpif (!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에 넣는 방식입니다.
phpif (!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단계. 웹에서 직접 열리는지 확인
bashcurl -I http://127.0.0.1/plugin/editor/t2editor/vendor/nsfwjs/models/custom_nsfw_v1/model.json
응답이 200 OK여야 합니다.
3단계. editor.lib.php 설정 변경
phpif (!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.js | 200 | vendor 경로 오류 |
| tf-backend-webgpu.min.js | 200 또는 미사용 | 백엔드 파일 없음 |
| nsfwjs.min.js | 200 | vendor 경로 오류 |
| model.json | 200 | URL 오타, 권한 문제 |
| *.bin | 200 | model.json 내부 weightsManifest 경로 문제 |
어떤 모델 타입을 써야 하나
현재 T2Editor 9.1.0 래퍼는 URL 기반 모델을 읽을 때 T2_NSFW_BROWSER_MODEL_TYPE을 nsfwjs load() 옵션으로 넘깁니다.
| 모델 계열 | 권장 type | 추가 옵션 | 비고 |
|---|---|---|---|
| MobileNetV2 | 생략 가능 | 필요 시 size: 224 | 가벼운 편 |
| MobileNetV2Mid | graph | 별도 size 없음 | 현재 기본 권장값 |
| InceptionV3 | 생략 가능 | size: 299 | 더 무거울 수 있음 |
| 직접 변환한 GraphModel | graph | 모델에 따라 다름 | TF SavedModel/Hub 변환 계열에 자주 해당 |
| 직접 변환한 LayersModel | null | 입력 크기 점검 필요 | 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 판정 로직은 다음 클래스명을 소문자 기준으로 읽습니다.
pornhentaisexyneutraldrawing
이 다섯 개가 유지되면 현재 UI와 바로 연결됩니다.
threshold 재조정
모델을 바꾸면 확률 분포가 달라질 수 있습니다. 그 경우 아래 임계값을 다시 조정해야 오탐/미탐을 줄일 수 있습니다.
jsunsafeExplicit unsafeCombined suspectExplicit suspectCombined suspectSexy
추천 운영 방식
가장 안전한 운영
MobileNetV2Mid유지- 자체 호스팅
model.json사용 graph유지webgpu -> webgl -> wasm -> cpu폴백 유지
실험용 운영
- 별도 폴더에 새 모델 설치
- 스테이징에서
T2_NSFW_BROWSER_MODEL_URL만 변경 - 샘플 이미지 세트로 결과 비교
- 문제가 없을 때 운영 반영
샘플 비교 체크리스트
- 일반 사진 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 옵션까지 안정적으로 다루려면, 차기 버전에서 예를 들어 아래 같은 설정 추가를 검토할 수 있습니다.
phpT2_NSFW_BROWSER_MODEL_SIZE
수정 요약
- 기본 제공 모델 외의 버전을 붙이는 절차를 별도 문서로 분리했습니다.
- URL 기반 모델, graph/layers 타입, 출력 클래스 호환 조건을 문서화했습니다.