OpenAI Privacy Filter 을 활용한 확장 가능한 웹 애플리케이션 구축 방법
요약
본 문서는 OpenAI Privacy Filter와 Gradio의 `gr.Server`를 결합하여 높은 수준의 사용자 경험을 제공하는 확장 가능한 웹 애플리케이션 구축 방법을 설명합니다. 이 아키텍처는 문서에서 PII(개인 식별 정보)를 탐지하고 강조 표시하거나, 이미지에서 민감한 정보를 검열하는 등 복잡한 데이터 처리 기능을 구현할 수 있게 합니다. 특히 `gr.Server`는 단일 큐잉 엔드포인트와 ZeroGPU 할당을 통해 백엔드 모델(Privacy Filter)의 강력함을 유지하면서도, 프론트엔드에서 부드러운 사용자 인터페이스(예: 독서 경험, 편집 가능한 이미지 주석)를 구현할 수 있도록 지원하는 핵심 역할을 합니다.
핵심 포인트
- **확장성 및 일관된 백엔드:** `gr.Server`는 모든 앱에 걸쳐 단일 큐잉 엔드포인트를 제공하여 코드 중복을 줄이고, 모델 호출의 일관성을 유지합니다.
- **고급 PII 탐지:** Privacy Filter(15억 파라미터)를 사용하여 문서 및 이미지에서 개인 식별 정보를 높은 정확도로 감지하고 카테고리화할 수 있습니다.
- **최적의 사용자 경험 (UX):** `gr.Server`와 Gradio 컴포넌트(`gr.HighlightedText`, `gr.ImageEditor`)를 결합하여, 서버 측 처리 결과를 클라이언트 측에서 부드럽게 렌더링하고 상호작용(예: 주석 추가, 필터 토글)할 수 있습니다.
- **기술적 이점:** ZeroGPU 할당 및 Gradio JS Client 사용을 통해 동시 업로드 처리와 브라우저 기반의 효율적인 통신이 가능합니다.
문서 프라이버시 탐색기 (Document Privacy Explorer): PDF 또는 DOCX 파일을 드롭하면, 모든 PII(개인정보) 스페인이 강조 표시된 채 문서를 다시 읽습니다.
이미지 익명화기 (Image Anonymizer): 이미지를 업로드하면 이름, 이메일, 계좌 번호 등 위에 빨간색 검열 바가 추가된 이미지로 반환됩니다. 캔버스에서 이미지는 편집 가능하므로 다운로드 전에 사용자 정의 주석을 작성할 수 있습니다.
스마트 리덕트 페이스트 (SmartRedact Paste): 민감한 텍스트를 붙여넣으면, 검열 버전이 제공되는 공개 URL 을 공유하고, 개인적으로 확인 링크를 유지합니다.
세 가지 모두 gradio.Server 를 기반으로 구축되었으며, 이는 커스텀 HTML/JS 프론트엔드와 Gradio 의 큐잉 (queueing), ZeroGPU 할당 및 gradio_client SDK 를 결합할 수 있게 합니다. 이 모든 앱에서 gradio.Server 는 동일한 백엔드 역할을 수행하며, 이것이 바로 그 힘을 발휘하는 핵심입니다.
Privacy Filter 는 Apache 2.0 라이선스 하에 허용적으로 배포된 15 억 (1.5B) 파라미터 모델로, 활성 파라미터는 5 천만 개 (50M) 입니다. PII 카테고리에는 private_person (개인), private_address (주소), private_email (이메일), private_phone (전화번호), private_url (URL), private_date (날짜), account_number (계좌 번호), secret (비밀) 이 포함됩니다. 컨텍스트 윈도우는 128,000 토큰이며, PII-Masking-300k 벤치마크에서 최상위 성능을 달성했습니다. 상세한 수치와 방법론은 공식 블로그에 나와 있습니다.
ysharma/OPF-Document-PII-Explorer 에서 시도해 보세요.
사용자 문제. PII 가 많은 문서 (계약서, 이력서, 내보낸 채팅 로그) 를 읽으시며, 모든 감지된 스페인을 카테고리별로 강조 표시하고, 필터를 사이드바에 배치하며, 상단에 요약 대시보드를 원합니다. 독서는 일반적인 문서처럼 느껴져야 하며, 양식처럼 느껴져서는 안 됩니다.
Privacy Filter 가 여기서 수행하는 역할. 전체 파일은 단일 128k 컨텍스트 포워드 패스 (forward pass) 를 통해 처리되므로, 청크링 (chunking), 스티칭 (stitching) 이 없으며, 스페인 오프셋이 렌더링된 텍스트와 정렬됩니다. BIOES 디코딩은 긴 모호한 구간을 통해 스페인 경계를 깔끔하게 유지합니다.
gr.Server 가 여기서 수행하는 역할. Blocks 와 gr.HighlightedText 를 사용하여 이를 연결할 수 있으며, 작동할 것입니다. 우리가 원했던 독서 경험 (세리프 본문, 클라이언트 측에서 CSS 클래스를 토글하여 재실행 없이 카테고리 필터, 페이지 리렌더링을 강요하지 않는 요약 대시보드) 는 작성하는 것이 더 쉬웠습니다. gr.Server 는 독자를 단일 HTML 파일로 제공하고, 하나의 큐잉 엔드포인트 뒤에 모델을 노출합니다:
import gradio as gr
from fastapi.responses import HTMLResponse
from gradio.data_classes import FileData
...
디코레이터에 주목하세요: @server.api(name="analyze_document") 는 단순한 @server.post 가 아닙니다. 이는 핸들러를 Gradio 의 큐잉과 연결하는 부분이며, 따라서 동시 업로드는 시리얼화되고, @spaces.GPU 는 ZeroGPU 에서 올바르게 구성되며, 브라우저와 gradio_client 모두에서 동일한 엔드포인트에 도달할 수 있습니다. 중복 코드가 없으며, 브라우저는 Gradio JS 클라이언트를 사용하여 호출합니다:
<script type="module">import { Client, handle_file } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
const client = await Client.connect(window.location.origin);
async function uploadFile(file) {
...
ysharma/OPF-Image-Anonymizer 에서 시도해 보세요.
사용자 문제. PII 가 있는 이미지 또는 스크린샷 (Slack 스레드, 영수증, Stripe 대시보드 등) 을 검열 바가 있는 상태로 공유하고 싶으며, 검열 바를 켜고 끌고, 재위치시키기 위해 드래그하거나, 모델이 놓친 부분을 손으로 그릴 수 있으며, 결과를 내보내고 싶습니다.
여기에서 프라이버시 필터가 하는 일. Tesseract 는 OCR 을 실행하고 단어별 경계 박스를 반환합니다. 백엔드는 문자 오프셋에 박스 매핑을 사용하여 전체 텍스트를 재구성한 후, 전체 텍스트 한 번에 Privacy Filter 를 실행합니다. 감지된 문자 스페인은 단어 매핑과 대조되고 줄당 픽셀 사각형으로 연결됩니다.
여기에서 gr.Server 가 하는 일.
gr.ImageEditor
은 레이어 어노테이션을 지원하며 이미지 리덕션 (redaction) 을 위한 합리적인 시작점입니다. 우리가 원했던 워크플로우 (바당별 카테고리 메타데이터, 한 번에 카테고리 내 모든 바 토글, 서버 라운드트립 없이 자연 해상도에서 클라이언트 측 PNG export) 는 커스텀 <canvas>
프론트엔드를 기반으로 구축하는 것이 더 깔끔했습니다.
gr.Server
는 하나의 큐잉 엔드포인트에서 픽셀 사각형을 반환하고 캔버스가 나머지 모든 것을 소유하도록 합니다:
@server.api(name="anonymize_screenshot")
def anonymize_screenshot(image: FileData) -> dict:
img = Image.open(image["path"]).convert("RGB")
...
프론트엔드는 client.predict("/anonymize_screenshot", { image: handle_file(file) })
와 동일한 패턴으로 호출합니다. 토글, 드래그, 새 바 그리기 및 PNG export 는 모두 브라우저에서 발생하며 수정은 서버로 라운드트립되지 않습니다.
ysharma/OPF-SmartRedact-Paste 에서 시도해 보세요.
사용자 문제. 공유 전에 리덕션 (redaction) 을 수행하는 pastebin 을 원합니다. 로그 라인, 이메일, 지원 티켓을 붙여넣습니다. 두 URL 이 반환됩니다. 공개 버전은 <PRIVATE_PERSON>
, <PRIVATE_EMAIL>
, <ACCOUNT_NUMBER>
와 같은 플레이스홀더를 사용하여 리덕션 컨벤션에 따라 리덕션된 버전을 제공합니다. 개인 버전은 토큰으로 보호되며 원본을 표시하고 스페인을 강조합니다.
여기에서 프라이버시 필터가 하는 일. 저장된 past 에 감지된 스페인 (span) 을 <CATEGORY>
플레이스홀더로 교체합니다. 이것이 전체 리덕션 단계입니다. 다국어 텍스트 (모델 카드 예제에 있는 스페인어, 프랑스어, 중국어, 힌디어 등) 는 변경 없이 동일한 호출을 통해 라우팅됩니다.
여기에서 gr.Server 가 하는 일. 이 앱은 같은 past ID 를 위한 두 개의 다른 GET 라우트를 필요로 하며, 하나는 공개이고 하나는 토큰 보호입니다. URL 형태가 중요하며, reveal URL 을 보관하는 것이 중요합니다.
gr.Server
는 FastAPI 앱 아래에 있으므로 여기서 작동합니다 — 이는 또한 @server.api
와 평범한 @server.get
이 같은 프로세스에서 옆으로 자리 잡을 수 있는 이유입니다. 참고: 이는 gr.Blocks()
를 사용하여 FastAPI 를 커스텀 라우트로 마운트하여 구축할 수도 있습니다:
# 모델 호출 → 큐잉 엔드포인트. 브라우저에서 client.predict("/create_paste", { text, ttl }) 를 통해 Hit.
@server.api(name="create_paste")
...
데몬 스레드는 30 초마다 만료된 past 을 제거합니다. 전체 서비스는 저장소를 포함하여 약 200 줄의 애플리케이션 코드로 구성됩니다. 모든 것이 하나의 프로세스에 있기 때문입니다.
세 앱에 걸친 분리는 동일합니다 — 모델에 닿는 것은 @server.api
를 통해, 나머지는 평범한 FastAPI 라우트를 유지합니다:
| 앱 | 큐잉 컴퓨팅 (@server.api ) |
|---|---|
| Document Privacy Explorer | analyze_document — 추출, 감지, 통계 |
| Image Anonymizer | anonymize_screenshot — OCR, 감지, 스페인 → 픽셀 박스 |
| SmartRedact Paste | create_paste — 감지, 리덕션, ID 마inting |
@server.api
는 Gradio 의 큐 (직렬화된 요청, 올바른 @spaces.GPU 를 제공) 를 제공합니다.
ZeroGPU, 진행 이벤트 (progress events) 및 @gradio/client 을 통해 브라우저가 접근하는 방식입니다. 동일한 엔드포인트는 Python 에서 gradio_client 사용자가 호출합니다 — 하나의 함수, 두 개의 SDK, 중복 코드 없음. Plain @server.get/@server.post 는 정적 표면 (static surfaces) 에만 예약되어 있습니다: HTML 페이지, 파일 조회, 저렴한 딕셔너리 읽기. 이는 gradio.Server 소개 포스트의 규칙이며, UI 가 매우 다르더라도 이 세 가지 앱이 일관된 느낌을 주는 이유입니다.
요약서, Slack 스레드의 스크린샷, 토큰이 포함된 로그 라인 등을 추가하세요. 재미있는 부분은 실제로 관심 있는 텍스트에서 Privacy Filter 가 무엇을 걸러내는지 (그리고 때로는 놓치는지) 확인하는 것입니다.
- OpenAI 의 출시 포스트: OpenAI Privacy Filter 소개
- 모델 카드: Hugging Face 에서 openai/privacy-filter
- 모델 카드상의 검열 예시 및 분류법
AI 자동 생성 콘텐츠
본 콘텐츠는 Hugging Face Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기