🔐로그인하면 문서 작성, 프로젝트 게시, ZIP 기반 버전 업로드, 브랜치 생성 기능을 사용할 수 있습니다. 로그인하러 가기
비교 대상 선택
추가 0줄 삭제 16줄 변경 0줄 동일 193줄
r1 파일 가져오기: guide-nsfwjs-overview.v9.1.0.md
2026-04-17 19:00

#가이드 #NSFW 코어 파일 문서 설정 문서 운영 설치 문서

요약

T2Editor 9.1.0의 NSFW 필터는 브라우저 모드를 기준으로 설계되어 있으며, 내부 엔진은 NSFWJS + TensorFlow.js 조합을 사용합니다. 모델은 기본적으로 MobileNetV2Mid를 사용하고, 런타임 자산은 CDN이 아니라 vendor/ 아래의 자체 호스팅 경로에서 읽도록 구성할 수 있습니다.

파일 개요

이 문서는 T2Editor 9.1.0에서 NSFWJS 관련 구조가 어떻게 바뀌었는지, 그리고 어떤 파일이 어떤 책임을 가지는지 한 번에 이해하기 위한 안내서입니다.

기존 구조에서는 브라우저 NSFW 코드가 자체 추론 로직과 워커 처리 중심으로 설명될 수 있었지만, 9.1.0에서는 다음 원칙으로 재정리되었습니다.

  • 엔진 교체: 자체 브라우저 추론 로직 → NSFWJS
  • 기본 모델 교체: 커스텀 분류 흐름 → MobileNetV2Mid
  • UI 유지: NSFWJS 자체 UI를 쓰지 않고 기존 이미지 업로드 UI에 결과만 연결
  • 운영 방식 변경: CDN 의존 대신 self-hosted vendor 구조 지원
  • 성능 전략 변경: webgpu -> webgl -> wasm -> cpu 순서 폴백

초보자와 웹마스터를 위한 이해

이 구조를 아주 간단히 보면 아래와 같습니다.

단계설명
1사용자가 이미지 업로드 모달에서 파일을 고릅니다.
2image.js가 브라우저 NSFW API를 불러옵니다.
3nsfw_api_browser.js가 NSFWJS 모델을 로드합니다.
4업로드 전 각 이미지가 safe / suspect / unsafe / error 중 하나로 분류됩니다.
5결과가 기존 미리보기 카드와 상태바에 반영됩니다.
6정책에 따라 업로드 허용, 경고 후 허용, 업로드 취소가 결정됩니다.

즉, NSFWJS는 보이는 UI를 담당하지 않고 분류 엔진만 담당합니다. 사용자가 실제로 보는 경고 배지, 상태바, 경고 모달은 T2Editor의 기존 이미지 플러그인이 담당합니다.

왜 이렇게 바뀌었나요?

가장 큰 이유는 아래 세 가지입니다.

  • 브라우저 추론 엔진을 유지보수하기 쉽게 만들기 위해
  • 기존 UI를 버리지 않고 필터 성능과 구조를 개선하기 위해
  • 서버 부하를 늘리지 않으면서 클라이언트 하드웨어를 활용하기 위해

전문 개발자를 위한 분석

전체 호출 흐름

text
editor.lib.php └─ window.T2EDITOR_NSFW_* 전역 설정 주입 └─ plugin/image/image.js ├─ getNSFWApi() │ └─ import(config/nsfw_api_browser.js) ├─ checkNSFW(file) │ └─ api.classify(file) ├─ resolveNSFWResult(imageData) └─ applyNSFWFilter(imageDataArray) └─ 업로드 허용/경고/차단 결정

핵심 파일별 책임

파일책임
editor.lib.phpNSFW 관련 설정 상수를 JS 전역 값으로 주입합니다.
config/nsfw_api_browser.jsNSFWJS 모델 로딩, 백엔드 선택, 이미지 분류를 담당합니다.
plugin/image/image.js업로드 모달, 상태 배지, 경고 모달, 업로드 정책 적용을 담당합니다.
plugin/image/image.css상태 배지, 상태바, 경고 표시의 시각 스타일을 담당합니다.

결과 라벨 체계

9.1.0의 브라우저 NSFW 결과는 단순히 safe / nsfw 두 단계가 아니라 아래처럼 다룹니다.

라벨의미기본 처리
safe업로드 가능으로 판단그대로 허용
suspect애매하거나 주의가 필요한 상태설정에 따라 경고 후 허용 또는 차단
unsafe고위험 이미지로 판단설정에 따라 차단 또는 경고 후 허용
error모델 로딩 또는 추론 실패오류 표시 후 정책에 따라 계속 진행

이 라벨 체계 때문에 문서와 코드에서 의심 이미지명확한 위험 이미지를 구분해서 다뤄야 합니다.

성능 구조

백엔드 우선순위

기본 우선순위는 다음과 같습니다.

text
webgpu -> webgl -> wasm -> cpu
  • webgpu: 가장 먼저 시도하는 가속 백엔드
  • webgl: 대부분의 브라우저에서 현실적인 폴백
  • wasm: GPU가 어렵거나 제한될 때 사용 가능한 안전한 폴백
  • cpu: 마지막 안전망

이 순서는 editor.lib.php에서 전역 설정으로 넘길 수 있고, nsfw_api_browser.js가 실제 선택을 수행합니다.

self-hosted 구조

운영에서는 아래 같은 구조를 권장합니다.

text
/plugin/editor/t2editor/vendor/ tfjs/ tfjs-backend-webgl/ tfjs-backend-webgpu/ tfjs-backend-wasm/ nsfwjs/ nsfwjs/models/mobilenet_v2_mid/

이렇게 하면 외부 CDN 장애나 차단의 영향을 줄이고, 배포 경로를 서비스 내부에서 통제할 수 있습니다.

수정 요약

9.1.0에서 NSFWJS 관련 핵심 변화는 아래와 같습니다.

  • 기존 브라우저 추론 코드 대신 NSFWJS 사용
  • MobileNetV2Mid 모델 도입
  • WebGPU 우선 백엔드 선택 지원
  • self-hosted vendor 자산 로딩 지원
  • 기존 이미지 UI에 맞춘 결과 연동
  • suspect 상태를 별도 정책 대상으로 추가
  • 업로드 직전 중복 재검사 비용 감소
읽는 순서

처음 보는 사람은 guide-nsfwjs-overviewconfig-nsfwjs-runtime-settingsops-nsfwjs-selfhost-webgpu-ubuntu 순서로 읽는 편이 좋습니다. 코드를 직접 수정할 사람은 core-nsfw_api_browser-js를 이어서 읽는 것이 안전합니다.

자주 생기는 오해

NSFWJS를 쓰면 UI도 자동으로 바뀌나요?

아닙니다. 이 구조에서는 NSFWJS가 분류 엔진만 담당하고, 배지·모달·상태바는 기존 T2Editor 이미지 플러그인이 담당합니다.

server 모드는 완전히 사라졌나요?

완전히 삭제된 것은 아닐 수 있지만, 9.1.0의 권장 경로는 브라우저 모드입니다. 문서와 운영 기본값도 브라우저 모드를 기준으로 작성하는 것이 맞습니다.

관련 문서

r2 고아 링크 삭제
2026-04-17 19:05

#가이드 #NSFW

요약

T2Editor 9.1.0의 NSFW 필터는 브라우저 모드를 기준으로 설계되어 있으며, 내부 엔진은 NSFWJS + TensorFlow.js 조합을 사용합니다. 모델은 기본적으로 MobileNetV2Mid를 사용하고, 런타임 자산은 CDN이 아니라 vendor/ 아래의 자체 호스팅 경로에서 읽도록 구성할 수 있습니다.

파일 개요

이 문서는 T2Editor 9.1.0에서 NSFWJS 관련 구조가 어떻게 바뀌었는지, 그리고 어떤 파일이 어떤 책임을 가지는지 한 번에 이해하기 위한 안내서입니다.

기존 구조에서는 브라우저 NSFW 코드가 자체 추론 로직과 워커 처리 중심으로 설명될 수 있었지만, 9.1.0에서는 다음 원칙으로 재정리되었습니다.

  • 엔진 교체: 자체 브라우저 추론 로직 → NSFWJS
  • 기본 모델 교체: 커스텀 분류 흐름 → MobileNetV2Mid
  • UI 유지: NSFWJS 자체 UI를 쓰지 않고 기존 이미지 업로드 UI에 결과만 연결
  • 운영 방식 변경: CDN 의존 대신 self-hosted vendor 구조 지원
  • 성능 전략 변경: webgpu -> webgl -> wasm -> cpu 순서 폴백

초보자와 웹마스터를 위한 이해

이 구조를 아주 간단히 보면 아래와 같습니다.

단계설명
1사용자가 이미지 업로드 모달에서 파일을 고릅니다.
2image.js가 브라우저 NSFW API를 불러옵니다.
3nsfw_api_browser.js가 NSFWJS 모델을 로드합니다.
4업로드 전 각 이미지가 safe / suspect / unsafe / error 중 하나로 분류됩니다.
5결과가 기존 미리보기 카드와 상태바에 반영됩니다.
6정책에 따라 업로드 허용, 경고 후 허용, 업로드 취소가 결정됩니다.

즉, NSFWJS는 보이는 UI를 담당하지 않고 분류 엔진만 담당합니다. 사용자가 실제로 보는 경고 배지, 상태바, 경고 모달은 T2Editor의 기존 이미지 플러그인이 담당합니다.

왜 이렇게 바뀌었나요?

가장 큰 이유는 아래 세 가지입니다.

  • 브라우저 추론 엔진을 유지보수하기 쉽게 만들기 위해
  • 기존 UI를 버리지 않고 필터 성능과 구조를 개선하기 위해
  • 서버 부하를 늘리지 않으면서 클라이언트 하드웨어를 활용하기 위해

전문 개발자를 위한 분석

전체 호출 흐름

text
editor.lib.php └─ window.T2EDITOR_NSFW_* 전역 설정 주입 └─ plugin/image/image.js ├─ getNSFWApi() │ └─ import(config/nsfw_api_browser.js) ├─ checkNSFW(file) │ └─ api.classify(file) ├─ resolveNSFWResult(imageData) └─ applyNSFWFilter(imageDataArray) └─ 업로드 허용/경고/차단 결정

핵심 파일별 책임

파일책임
editor.lib.phpNSFW 관련 설정 상수를 JS 전역 값으로 주입합니다.
config/nsfw_api_browser.jsNSFWJS 모델 로딩, 백엔드 선택, 이미지 분류를 담당합니다.
plugin/image/image.js업로드 모달, 상태 배지, 경고 모달, 업로드 정책 적용을 담당합니다.
plugin/image/image.css상태 배지, 상태바, 경고 표시의 시각 스타일을 담당합니다.

결과 라벨 체계

9.1.0의 브라우저 NSFW 결과는 단순히 safe / nsfw 두 단계가 아니라 아래처럼 다룹니다.

라벨의미기본 처리
safe업로드 가능으로 판단그대로 허용
suspect애매하거나 주의가 필요한 상태설정에 따라 경고 후 허용 또는 차단
unsafe고위험 이미지로 판단설정에 따라 차단 또는 경고 후 허용
error모델 로딩 또는 추론 실패오류 표시 후 정책에 따라 계속 진행

이 라벨 체계 때문에 문서와 코드에서 의심 이미지명확한 위험 이미지를 구분해서 다뤄야 합니다.

성능 구조

백엔드 우선순위

기본 우선순위는 다음과 같습니다.

text
webgpu -> webgl -> wasm -> cpu
  • webgpu: 가장 먼저 시도하는 가속 백엔드
  • webgl: 대부분의 브라우저에서 현실적인 폴백
  • wasm: GPU가 어렵거나 제한될 때 사용 가능한 안전한 폴백
  • cpu: 마지막 안전망

이 순서는 editor.lib.php에서 전역 설정으로 넘길 수 있고, nsfw_api_browser.js가 실제 선택을 수행합니다.

self-hosted 구조

운영에서는 아래 같은 구조를 권장합니다.

text
/plugin/editor/t2editor/vendor/ tfjs/ tfjs-backend-webgl/ tfjs-backend-webgpu/ tfjs-backend-wasm/ nsfwjs/ nsfwjs/models/mobilenet_v2_mid/

이렇게 하면 외부 CDN 장애나 차단의 영향을 줄이고, 배포 경로를 서비스 내부에서 통제할 수 있습니다.

수정 요약

9.1.0에서 NSFWJS 관련 핵심 변화는 아래와 같습니다.

  • 기존 브라우저 추론 코드 대신 NSFWJS 사용
  • MobileNetV2Mid 모델 도입
  • WebGPU 우선 백엔드 선택 지원
  • self-hosted vendor 자산 로딩 지원
  • 기존 이미지 UI에 맞춘 결과 연동
  • suspect 상태를 별도 정책 대상으로 추가
  • 업로드 직전 중복 재검사 비용 감소

자주 생기는 오해

NSFWJS를 쓰면 UI도 자동으로 바뀌나요?

아닙니다. 이 구조에서는 NSFWJS가 분류 엔진만 담당하고, 배지·모달·상태바는 기존 T2Editor 이미지 플러그인이 담당합니다.

server 모드는 완전히 사라졌나요?

완전히 삭제된 것은 아닐 수 있지만, 9.1.0의 권장 경로는 브라우저 모드입니다. 문서와 운영 기본값도 브라우저 모드를 기준으로 작성하는 것이 맞습니다.

라인 단위 비교
이전 새 버전
1 --- 1 ---
2 title: 가이드: NSFWJS 기반 이미지 필터 개요 2 title: 가이드: NSFWJS 기반 이미지 필터 개요
3 document_id: guide-nsfwjs-overview 3 document_id: guide-nsfwjs-overview
4 slug: guide-nsfwjs-overview 4 slug: guide-nsfwjs-overview
5 target_editor_version: 9.1.0 5 target_editor_version: 9.1.0
6 document_type: guide 6 document_type: guide
7 doc_type: guide 7 doc_type: guide
8 target_readers: [초보자, 웹마스터, 개발자, AI agent] 8 target_readers: [초보자, 웹마스터, 개발자, AI agent]
9 importance: High 9 importance: High
10 dependency: High 10 dependency: High
11 core_type: Guide 11 core_type: Guide
12 stability: [Stable Anchor, Version-Bound] 12 stability: [Stable Anchor, Version-Bound]
13 stable_anchor: [브라우저 우선 구조, 이미지 플러그인 연동, 결과 라벨 체계] 13 stable_anchor: [브라우저 우선 구조, 이미지 플러그인 연동, 결과 라벨 체계]
14 version_bound: [window 전역 설정 키, 백엔드 우선순위 기본값, self-hosted vendor 경로] 14 version_bound: [window 전역 설정 키, 백엔드 우선순위 기본값, self-hosted vendor 경로]
15 related_docs: 15 related_docs:
16 - core-nsfw_api_browser-js 16 - core-nsfw_api_browser-js
17 - config-nsfwjs-runtime-settings 17 - config-nsfwjs-runtime-settings
18 - ops-nsfwjs-selfhost-webgpu-ubuntu 18 - ops-nsfwjs-selfhost-webgpu-ubuntu
19 - migration-legacy-nsfw-to-nsfwjs 19 - migration-legacy-nsfw-to-nsfwjs
20 related_files: 20 related_files:
21 - 9.1.0/t2editor/config/nsfw_api_browser.js 21 - 9.1.0/t2editor/config/nsfw_api_browser.js
22 - 9.1.0/t2editor/plugin/image/image.js 22 - 9.1.0/t2editor/plugin/image/image.js
23 - 9.1.0/t2editor/editor.lib.php 23 - 9.1.0/t2editor/editor.lib.php
24 related_functions: 24 related_functions:
25 - load 25 - load
26 - classify 26 - classify
27 - checkNSFW 27 - checkNSFW
28 - applyNSFWFilter 28 - applyNSFWFilter
29 related_classes_modules: 29 related_classes_modules:
30 - NSFWFilterAPI 30 - NSFWFilterAPI
31 - ImagePlugin 31 - ImagePlugin
32 related_features: 32 related_features:
33 - 브라우저 NSFW 검사 33 - 브라우저 NSFW 검사
34 - self-hosted 모델 로딩 34 - self-hosted 모델 로딩
35 - WebGPU 우선 백엔드 선택 35 - WebGPU 우선 백엔드 선택
36 - 이미지 업로드 경고 처리 36 - 이미지 업로드 경고 처리
37 related_ui: 37 related_ui:
38 - 이미지 업로드 모달 38 - 이미지 업로드 모달
39 - 미리보기 카드 상태 배지 39 - 미리보기 카드 상태 배지
40 - NSFW 상태바 40 - NSFW 상태바
41 change_risk: 판정 기준과 로딩 경로를 동시에 변경하면 업로드 UX, 성능, 운영 배포 경로가 함께 영향을 받습니다. 41 change_risk: 판정 기준과 로딩 경로를 동시에 변경하면 업로드 UX, 성능, 운영 배포 경로가 함께 영향을 받습니다.
42 reading_order: 18 42 reading_order: 18
43 summary: T2Editor 9.1.0에서 NSFWJS 기반 브라우저 이미지 필터가 어떤 구조로 동작하는지 설명합니다. 43 summary: T2Editor 9.1.0에서 NSFWJS 기반 브라우저 이미지 필터가 어떤 구조로 동작하는지 설명합니다.
44 description: 자체 추론 로직에서 NSFWJS MobileNetV2Mid 기반 구조로 전환된 배경과 파일 간 호출 흐름을 정리한 문서입니다. 44 description: 자체 추론 로직에서 NSFWJS MobileNetV2Mid 기반 구조로 전환된 배경과 파일 간 호출 흐름을 정리한 문서입니다.
45 tags: [NSFWJS, browser-nsfw, self-hosted, webgpu, T2Editor, guide] 45 tags: [NSFWJS, browser-nsfw, self-hosted, webgpu, T2Editor, guide]
46 version_tag: 9.1.0 46 version_tag: 9.1.0
47 maintenance_difficulty: Medium 47 maintenance_difficulty: Medium
48 test_requirement: High 48 test_requirement: High
49 ai_agent_risk: Medium 49 ai_agent_risk: Medium
50 source_basis: [현재 코드 분석 기반] 50 source_basis: [현재 코드 분석 기반]
51 beginner_section_included: true 51 beginner_section_included: true
52 webmaster_section_included: true 52 webmaster_section_included: true
53 developer_section_included: true 53 developer_section_included: true
54 --- 54 ---
55   55  
56 [목차] 56 [목차]
57   57  
58 [[분류:가이드]] 58 [[분류:가이드]]
59 [[분류:NSFW]] 59 [[분류:NSFW]]
60 [[core-nsfw_api_browser-js|코어 파일 문서]]  
61 [[config-nsfwjs-runtime-settings|설정 문서]]  
62 [[ops-nsfwjs-selfhost-webgpu-ubuntu|운영 설치 문서]]  
63   60  
64 [note(요약)] 61 [note(요약)]
65 T2Editor 9.1.0의 NSFW 필터는 **브라우저 모드**를 기준으로 설계되어 있으며, 내부 엔진은 **NSFWJS + TensorFlow.js** 조합을 사용합니다. 62 T2Editor 9.1.0의 NSFW 필터는 **브라우저 모드**를 기준으로 설계되어 있으며, 내부 엔진은 **NSFWJS + TensorFlow.js** 조합을 사용합니다.
66 모델은 기본적으로 `MobileNetV2Mid`를 사용하고, 런타임 자산은 CDN이 아니라 `vendor/` 아래의 **자체 호스팅 경로**에서 읽도록 구성할 수 있습니다. 63 모델은 기본적으로 `MobileNetV2Mid`를 사용하고, 런타임 자산은 CDN이 아니라 `vendor/` 아래의 **자체 호스팅 경로**에서 읽도록 구성할 수 있습니다.
67 [/note] 64 [/note]
68   65  
69 # 파일 개요 66 # 파일 개요
70   67  
71 이 문서는 T2Editor 9.1.0에서 NSFWJS 관련 구조가 어떻게 바뀌었는지, 그리고 어떤 파일이 어떤 책임을 가지는지 한 번에 이해하기 위한 안내서입니다. 68 이 문서는 T2Editor 9.1.0에서 NSFWJS 관련 구조가 어떻게 바뀌었는지, 그리고 어떤 파일이 어떤 책임을 가지는지 한 번에 이해하기 위한 안내서입니다.
72   69  
73 기존 구조에서는 브라우저 NSFW 코드가 자체 추론 로직과 워커 처리 중심으로 설명될 수 있었지만, 9.1.0에서는 다음 원칙으로 재정리되었습니다. 70 기존 구조에서는 브라우저 NSFW 코드가 자체 추론 로직과 워커 처리 중심으로 설명될 수 있었지만, 9.1.0에서는 다음 원칙으로 재정리되었습니다.
74   71  
75 - **엔진 교체**: 자체 브라우저 추론 로직 → `NSFWJS` 72 - **엔진 교체**: 자체 브라우저 추론 로직 → `NSFWJS`
76 - **기본 모델 교체**: 커스텀 분류 흐름 → `MobileNetV2Mid` 73 - **기본 모델 교체**: 커스텀 분류 흐름 → `MobileNetV2Mid`
77 - **UI 유지**: NSFWJS 자체 UI를 쓰지 않고 기존 이미지 업로드 UI에 결과만 연결 74 - **UI 유지**: NSFWJS 자체 UI를 쓰지 않고 기존 이미지 업로드 UI에 결과만 연결
78 - **운영 방식 변경**: CDN 의존 대신 self-hosted vendor 구조 지원 75 - **운영 방식 변경**: CDN 의존 대신 self-hosted vendor 구조 지원
79 - **성능 전략 변경**: `webgpu -> webgl -> wasm -> cpu` 순서 폴백 76 - **성능 전략 변경**: `webgpu -> webgl -> wasm -> cpu` 순서 폴백
80   77  
81 ## 초보자와 웹마스터를 위한 이해 78 ## 초보자와 웹마스터를 위한 이해
82   79  
83 이 구조를 아주 간단히 보면 아래와 같습니다. 80 이 구조를 아주 간단히 보면 아래와 같습니다.
84   81  
85 ||= 단계 ||= 설명 || 82 ||= 단계 ||= 설명 ||
86 || 1 || 사용자가 이미지 업로드 모달에서 파일을 고릅니다. || 83 || 1 || 사용자가 이미지 업로드 모달에서 파일을 고릅니다. ||
87 || 2 || `image.js`가 브라우저 NSFW API를 불러옵니다. || 84 || 2 || `image.js`가 브라우저 NSFW API를 불러옵니다. ||
88 || 3 || `nsfw_api_browser.js`가 NSFWJS 모델을 로드합니다. || 85 || 3 || `nsfw_api_browser.js`가 NSFWJS 모델을 로드합니다. ||
89 || 4 || 업로드 전 각 이미지가 `safe / suspect / unsafe / error` 중 하나로 분류됩니다. || 86 || 4 || 업로드 전 각 이미지가 `safe / suspect / unsafe / error` 중 하나로 분류됩니다. ||
90 || 5 || 결과가 기존 미리보기 카드와 상태바에 반영됩니다. || 87 || 5 || 결과가 기존 미리보기 카드와 상태바에 반영됩니다. ||
91 || 6 || 정책에 따라 업로드 허용, 경고 후 허용, 업로드 취소가 결정됩니다. || 88 || 6 || 정책에 따라 업로드 허용, 경고 후 허용, 업로드 취소가 결정됩니다. ||
92   89  
93 즉, **NSFWJS는 보이는 UI를 담당하지 않고 분류 엔진만 담당**합니다. 90 즉, **NSFWJS는 보이는 UI를 담당하지 않고 분류 엔진만 담당**합니다.
94 사용자가 실제로 보는 경고 배지, 상태바, 경고 모달은 T2Editor의 기존 이미지 플러그인이 담당합니다. 91 사용자가 실제로 보는 경고 배지, 상태바, 경고 모달은 T2Editor의 기존 이미지 플러그인이 담당합니다.
95   92  
96 ### 왜 이렇게 바뀌었나요? 93 ### 왜 이렇게 바뀌었나요?
97   94  
98 가장 큰 이유는 아래 세 가지입니다. 95 가장 큰 이유는 아래 세 가지입니다.
99   96  
100 - 브라우저 추론 엔진을 유지보수하기 쉽게 만들기 위해 97 - 브라우저 추론 엔진을 유지보수하기 쉽게 만들기 위해
101 - 기존 UI를 버리지 않고 필터 성능과 구조를 개선하기 위해 98 - 기존 UI를 버리지 않고 필터 성능과 구조를 개선하기 위해
102 - 서버 부하를 늘리지 않으면서 클라이언트 하드웨어를 활용하기 위해 99 - 서버 부하를 늘리지 않으면서 클라이언트 하드웨어를 활용하기 위해
103   100  
104 ## 전문 개발자를 위한 분석 101 ## 전문 개발자를 위한 분석
105   102  
106 ## 전체 호출 흐름 103 ## 전체 호출 흐름
107   104  
108 ```text 105 ```text
109 editor.lib.php 106 editor.lib.php
110 └─ window.T2EDITOR_NSFW_* 전역 설정 주입 107 └─ window.T2EDITOR_NSFW_* 전역 설정 주입
111 └─ plugin/image/image.js 108 └─ plugin/image/image.js
112 ├─ getNSFWApi() 109 ├─ getNSFWApi()
113 │ └─ import(config/nsfw_api_browser.js) 110 │ └─ import(config/nsfw_api_browser.js)
114 ├─ checkNSFW(file) 111 ├─ checkNSFW(file)
115 │ └─ api.classify(file) 112 │ └─ api.classify(file)
116 ├─ resolveNSFWResult(imageData) 113 ├─ resolveNSFWResult(imageData)
117 └─ applyNSFWFilter(imageDataArray) 114 └─ applyNSFWFilter(imageDataArray)
118 └─ 업로드 허용/경고/차단 결정 115 └─ 업로드 허용/경고/차단 결정
119 ``` 116 ```
120   117  
121 ### 핵심 파일별 책임 118 ### 핵심 파일별 책임
122   119  
123 ||= 파일 ||= 책임 || 120 ||= 파일 ||= 책임 ||
124 || `editor.lib.php` || NSFW 관련 설정 상수를 JS 전역 값으로 주입합니다. || 121 || `editor.lib.php` || NSFW 관련 설정 상수를 JS 전역 값으로 주입합니다. ||
125 || `config/nsfw_api_browser.js` || NSFWJS 모델 로딩, 백엔드 선택, 이미지 분류를 담당합니다. || 122 || `config/nsfw_api_browser.js` || NSFWJS 모델 로딩, 백엔드 선택, 이미지 분류를 담당합니다. ||
126 || `plugin/image/image.js` || 업로드 모달, 상태 배지, 경고 모달, 업로드 정책 적용을 담당합니다. || 123 || `plugin/image/image.js` || 업로드 모달, 상태 배지, 경고 모달, 업로드 정책 적용을 담당합니다. ||
127 || `plugin/image/image.css` || 상태 배지, 상태바, 경고 표시의 시각 스타일을 담당합니다. || 124 || `plugin/image/image.css` || 상태 배지, 상태바, 경고 표시의 시각 스타일을 담당합니다. ||
128   125  
129 ## 결과 라벨 체계 126 ## 결과 라벨 체계
130   127  
131 9.1.0의 브라우저 NSFW 결과는 단순히 `safe / nsfw` 두 단계가 아니라 아래처럼 다룹니다. 128 9.1.0의 브라우저 NSFW 결과는 단순히 `safe / nsfw` 두 단계가 아니라 아래처럼 다룹니다.
132   129  
133 ||= 라벨 ||= 의미 ||= 기본 처리 || 130 ||= 라벨 ||= 의미 ||= 기본 처리 ||
134 || `safe` || 업로드 가능으로 판단 || 그대로 허용 || 131 || `safe` || 업로드 가능으로 판단 || 그대로 허용 ||
135 || `suspect` || 애매하거나 주의가 필요한 상태 || 설정에 따라 경고 후 허용 또는 차단 || 132 || `suspect` || 애매하거나 주의가 필요한 상태 || 설정에 따라 경고 후 허용 또는 차단 ||
136 || `unsafe` || 고위험 이미지로 판단 || 설정에 따라 차단 또는 경고 후 허용 || 133 || `unsafe` || 고위험 이미지로 판단 || 설정에 따라 차단 또는 경고 후 허용 ||
137 || `error` || 모델 로딩 또는 추론 실패 || 오류 표시 후 정책에 따라 계속 진행 || 134 || `error` || 모델 로딩 또는 추론 실패 || 오류 표시 후 정책에 따라 계속 진행 ||
138   135  
139 이 라벨 체계 때문에 문서와 코드에서 **의심 이미지**와 **명확한 위험 이미지**를 구분해서 다뤄야 합니다. 136 이 라벨 체계 때문에 문서와 코드에서 **의심 이미지**와 **명확한 위험 이미지**를 구분해서 다뤄야 합니다.
140   137  
141 ## 성능 구조 138 ## 성능 구조
142   139  
143 ### 백엔드 우선순위 140 ### 백엔드 우선순위
144   141  
145 기본 우선순위는 다음과 같습니다. 142 기본 우선순위는 다음과 같습니다.
146   143  
147 ```text 144 ```text
148 webgpu -> webgl -> wasm -> cpu 145 webgpu -> webgl -> wasm -> cpu
149 ``` 146 ```
150   147  
151 - `webgpu`: 가장 먼저 시도하는 가속 백엔드 148 - `webgpu`: 가장 먼저 시도하는 가속 백엔드
152 - `webgl`: 대부분의 브라우저에서 현실적인 폴백 149 - `webgl`: 대부분의 브라우저에서 현실적인 폴백
153 - `wasm`: GPU가 어렵거나 제한될 때 사용 가능한 안전한 폴백 150 - `wasm`: GPU가 어렵거나 제한될 때 사용 가능한 안전한 폴백
154 - `cpu`: 마지막 안전망 151 - `cpu`: 마지막 안전망
155   152  
156 이 순서는 `editor.lib.php`에서 전역 설정으로 넘길 수 있고, `nsfw_api_browser.js`가 실제 선택을 수행합니다. 153 이 순서는 `editor.lib.php`에서 전역 설정으로 넘길 수 있고, `nsfw_api_browser.js`가 실제 선택을 수행합니다.
157   154  
158 ### self-hosted 구조 155 ### self-hosted 구조
159   156  
160 운영에서는 아래 같은 구조를 권장합니다. 157 운영에서는 아래 같은 구조를 권장합니다.
161   158  
162 ```text 159 ```text
163 /plugin/editor/t2editor/vendor/ 160 /plugin/editor/t2editor/vendor/
164 tfjs/ 161 tfjs/
165 tfjs-backend-webgl/ 162 tfjs-backend-webgl/
166 tfjs-backend-webgpu/ 163 tfjs-backend-webgpu/
167 tfjs-backend-wasm/ 164 tfjs-backend-wasm/
168 nsfwjs/ 165 nsfwjs/
169 nsfwjs/models/mobilenet_v2_mid/ 166 nsfwjs/models/mobilenet_v2_mid/
170 ``` 167 ```
171   168  
172 이렇게 하면 외부 CDN 장애나 차단의 영향을 줄이고, 배포 경로를 서비스 내부에서 통제할 수 있습니다. 169 이렇게 하면 외부 CDN 장애나 차단의 영향을 줄이고, 배포 경로를 서비스 내부에서 통제할 수 있습니다.
173   170  
174 ## 수정 요약 171 ## 수정 요약
175   172  
176 9.1.0에서 NSFWJS 관련 핵심 변화는 아래와 같습니다. 173 9.1.0에서 NSFWJS 관련 핵심 변화는 아래와 같습니다.
177   174  
178 - 기존 브라우저 추론 코드 대신 NSFWJS 사용 175 - 기존 브라우저 추론 코드 대신 NSFWJS 사용
179 - `MobileNetV2Mid` 모델 도입 176 - `MobileNetV2Mid` 모델 도입
180 - WebGPU 우선 백엔드 선택 지원 177 - WebGPU 우선 백엔드 선택 지원
181 - self-hosted vendor 자산 로딩 지원 178 - self-hosted vendor 자산 로딩 지원
182 - 기존 이미지 UI에 맞춘 결과 연동 179 - 기존 이미지 UI에 맞춘 결과 연동
183 - `suspect` 상태를 별도 정책 대상으로 추가 180 - `suspect` 상태를 별도 정책 대상으로 추가
184 - 업로드 직전 중복 재검사 비용 감소 181 - 업로드 직전 중복 재검사 비용 감소
185   182  
186 [tip(읽는 순서)]  
187 처음 보는 사람은 [[guide-nsfwjs-overview]] → [[config-nsfwjs-runtime-settings]] → [[ops-nsfwjs-selfhost-webgpu-ubuntu]] 순서로 읽는 편이 좋습니다.  
188 코드를 직접 수정할 사람은 [[core-nsfw_api_browser-js]]를 이어서 읽는 것이 안전합니다.  
189 [/tip]  
190  
191 ## 자주 생기는 오해 183 ## 자주 생기는 오해
192   184  
193 [folding(NSFWJS를 쓰면 UI도 자동으로 바뀌나요?)] 185 [folding(NSFWJS를 쓰면 UI도 자동으로 바뀌나요?)]
194 아닙니다. 186 아닙니다.
195 이 구조에서는 NSFWJS가 분류 엔진만 담당하고, 배지·모달·상태바는 기존 T2Editor 이미지 플러그인이 담당합니다. 187 이 구조에서는 NSFWJS가 분류 엔진만 담당하고, 배지·모달·상태바는 기존 T2Editor 이미지 플러그인이 담당합니다.
196 [/folding] 188 [/folding]
197   189  
198 [folding(server 모드는 완전히 사라졌나요?)] 190 [folding(server 모드는 완전히 사라졌나요?)]
199 완전히 삭제된 것은 아닐 수 있지만, 9.1.0의 권장 경로는 브라우저 모드입니다. 191 완전히 삭제된 것은 아닐 수 있지만, 9.1.0의 권장 경로는 브라우저 모드입니다.
200 문서와 운영 기본값도 브라우저 모드를 기준으로 작성하는 것이 맞습니다. 192 문서와 운영 기본값도 브라우저 모드를 기준으로 작성하는 것이 맞습니다.
201 [/folding] 193 [/folding]
202  
203 ## 관련 문서  
204  
205 - [[core-nsfw_api_browser-js|코어 파일: nsfw_api_browser.js]]  
206 - [[config-nsfwjs-runtime-settings|설정: NSFWJS 런타임과 모델 경로]]  
207 - [[ops-nsfwjs-selfhost-webgpu-ubuntu|운영: Ubuntu self-hosted + WebGPU 설치]]  
208 - [[migration-legacy-nsfw-to-nsfwjs|마이그레이션: 레거시 NSFW 구조에서 NSFWJS로]]  
209  
✏ 이 상태를 참고해 편집
T2WIKI · 기술 통합 위키 & 프로젝트 허브 · 나무위키 + Markdown 완벽 지원 · SQLite · PHP 8.2 · 소개 · 문법 안내