如何使用 OpenAI 的 Privacy Filter 构建可扩展的 Web 应用

Hugging Face Blog 工具

摘要

本文演示如何利用 OpenAI 的 Privacy Filter 模型和 Gradio Server 构建用于 PII(个人可识别信息)检测的可扩展 Web 应用,并展示了文档探索、图像匿名化等三个具体应用示例。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/08 09:01

如何使用 OpenAI Privacy Filter 构建可扩展的 Web 应用

来源:https://huggingface.co/blog/openai-privacy-filter-web-apps

返回文章列表

OpenAI 本周在 Hugging Face Hub 上发布了 Privacy Filter:一款开源的个人可识别信息(PII)检测器,能在单次前向传播中,基于 128k 上下文对八种文本类别进行标注。模型卡片

我们花了几小时用它构建应用,最终做出了三个 demo,分别展示了该模型的不同能力维度:

  • 文档隐私浏览器:拖入 PDF 或 DOCX 文件,文档会以高亮形式展示所有检测到的 PII 片段。
  • 图像匿名化工具:上传图片,返回带有黑色遮罩条(覆盖姓名、邮箱、账号等)的版本。图片可在画布上编辑,支持手动添加标注后再下载。
  • SmartRedact 粘贴板:粘贴敏感文本,获得一个公开 URL(展示脱敏版本),同时保留一个私有查看链接。

三者均基于 gradio.Server 构建,该工具让你可以将自定义 HTML/JS 前端与 Gradio 的队列管理、ZeroGPU 资源分配以及 gradio_client SDK 结合使用。在这些应用中,gradio.Server 都扮演着相同的后端角色,这种一致性正是其强大之处。

模型介绍

Privacy Filter 是一个 15 亿参数、5000 万活跃参数的模型,采用宽松的 Apache 2.0 许可证。PII 类别包括:private_personprivate_addressprivate_emailprivate_phoneprivate_urlprivate_dateaccount_numbersecret。上下文长度为 128,000 tokens,在 PII-Masking-300k 基准测试 上达到了最先进的性能。完整数据和方法论详见官方发布博客

1. 文档隐私浏览器

ysharma/OPF-Document-PII-Explorer 体验。

用户痛点。 你想阅读一份 PII 密集的文档(合同、简历、导出的聊天记录),需要按类别高亮所有检测到的片段,侧边栏有过滤器,顶部有汇总面板。阅读体验应该像普通文档一样自然,而不是表单。

Privacy Filter 在这里的作用。 整个文件通过单次 128k 上下文的前向传播处理,无需分块、无需拼接,片段偏移量与渲染文本直接对齐。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 = gr.Server()

@server.get("/", response_class=HTMLResponse)
async def homepage():
    return FRONTEND_HTML  # 阅读视图;见 app.py

@server.api(name="analyze_document")
def analyze_document(file: FileData) -> dict:
    text = extract_text(file["path"])  # PyMuPDF / python-docx
    source_text, spans = run_privacy_filter(text)  # 单次 128k 传播
    return {
        "text": source_text,
        "spans": spans,  # [{start, end, label}, ...]
        "stats": compute_stats(source_text, spans),
    }

注意装饰器:@server.api(name="analyze_document"),不是简单的 @server.post。这一步将处理程序接入 Gradio 的队列,使得并发上传被序列化、@spaces.GPU 在 ZeroGPU 上正确组合,且同一端点可从浏览器和 gradio_client 访问,无需重复代码。

浏览器通过 Gradio JS 客户端调用:

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) {
  const result = await client.predict("/analyze_document", {
    file: handle_file(file)
  });
  renderResults(result.data[0]);  // { text, spans, stats }
}

2. 图像匿名化工具

ysharma/OPF-Image-Anonymizer 体验。

用户痛点。 你想分享一张图片或截图(Slack 对话、收据、Stripe 后台),但需要用黑色遮罩条覆盖 PII。你希望开关遮罩条、拖拽调整位置,或手动绘制遮罩条以补充模型遗漏的内容,然后导出结果。

Privacy Filter 在这里的作用。 Tesseract 运行 OCR 并返回逐词的边界框。后端重建完整文本并建立字符偏移到框的映射,然后对整段文本运行一次 Privacy Filter。检测到的字符片段通过词映射查找,并按行合并为像素矩形。

gr.Server 在这里的作用。 gr.ImageEditor 支持分层标注,是图像脱敏的合理起点。但我们想要的工作流(每条遮罩条的类别元数据、一键开关某类别的所有遮罩条、客户端以原始分辨率导出 PNG 无需服务器往返)更适合在自定义前端上构建。gr.Server 从一个队列化端点返回像素矩形,其余由画布自行处理:

@server.api(name="anonymize_screenshot")
def anonymize_screenshot(image: FileData) -> dict:
    img = Image.open(image["path"]).convert("RGB")
    full_text, char_to_box = ocr_image(img)  # 逐词框 + 字符映射
    spans = run_privacy_filter(full_text)
    boxes = spans_to_pixel_boxes(spans, char_to_box)
    return {
        "image_data_url": pil_to_base64(img),
        "width": img.width,
        "height": img.height,
        "boxes": boxes,  # [{x, y, w, h, label, text}, ...]
    }

前端通过 client.predict("/anonymize_screenshot", { image: handle_file(file) }) 调用,与上述模式相同。开关、拖拽、新建遮罩条、PNG 导出都在浏览器中完成;编辑无需向服务器发送请求。

3. SmartRedact 粘贴板

ysharma/OPF-SmartRedact-Paste 体验。

用户痛点。 你想要一个先脱敏再分享的 pastebin。粘贴日志行、邮件、工单,获得两个 URL。公开 URL 展示用 <PERSON><EMAIL><ACCOUNT> 等占位符替换的版本,遵循官方博客示例 的脱敏约定。私有 URL 通过你保留的 token 访问,展示带高亮片段的原始文本。

Privacy Filter 在这里的作用。 将每个检测到的片段替换为 <CATEGORY> 占位符存储在粘贴中。这就是完整的脱敏步骤。多语言文本(西班牙语、法语、中文、印地语等,见模型卡片示例)通过同一调用处理,无需修改。

gr.Server 在这里的作用。 该应用需要为同一粘贴 ID 提供两个不同的 GET 路由,一个公开,一个 token gated,且 URL 形态很重要,因为查看 URL 是你需要保留的东西。gr.Server 适用是因为底层是 FastAPI——这也是 @server.api 和普通 @server.get 可以并存于同一进程的原因。注意:这也可以通过 gr.Blocks() 挂载自定义 FastAPI 路由 实现:

# 模型调用 → 队列化端点。通过浏览器调用:
# client.predict("/create_paste", { text, ttl })
@server.api(name="create_paste")
def create_paste(text: str, ttl: str = "never") -> dict:
    source_text, spans = run_privacy_filter(text)
    redacted = redact(source_text, spans)  # 占位符
    pid, reveal_token = secrets.token_urlsafe(6), secrets.token_urlsafe(22)
    PASTES[pid] = Paste(pid, reveal_token, source_text, redacted, spans, expires_at=_ttl(ttl))  # 见 app.py
    return {
        "view_path": f"/view/{pid}",
        "reveal_path": f"/view/{pid}?token={reveal_token}",
    }

# 查看页面 → 普通 FastAPI GET。无模型、无需队列,
# 且我们需要 `/view/{pid}?token=...` 这种队列端点无法提供的定制 URL 形态。
@server.get("/view/{pid}", response_class=HTMLResponse)
async def view_paste(pid: str, token: str | None = None):
    p = _store_get(pid)  # 见 app.py 存储实现
    if p is None:
        return HTMLResponse(_not_found(), status_code=404)
    revealed = bool(token) and secrets.compare_digest(token, p.reveal_token)
    return HTMLResponse(_render_view(p, revealed))

守护线程每 30 秒清理过期粘贴。整个服务包括存储在内仅约 200 行应用代码,因为所有内容都在一个进程中。

gradio.Server 提供了什么

三个应用的分层方式相同——任何涉及模型的操作通过 @server.api,其余保持为普通 FastAPI 路由:

应用队列计算(@server.api普通 FastAPI 路由
文档隐私浏览器analyze_document — 提取、检测、统计GET / 提供自定义阅读视图
图像匿名化工具anonymize_screenshot — OCR、检测、片段 → 像素框GET / + GET /examples/* 提供画布 UI 和预加载示例
SmartRedact 粘贴板create_paste — 检测、脱敏、生成 IDGET / 组合页面,GET /view/{pid}?token=... 公开 + token gated 视图,GET /api/paste/{pid} JSON 查询

@server.api 提供 Gradio 的队列(序列化请求、ZeroGPU 上正确的 @spaces.GPU 组合、进度事件),浏览器通过 @gradio/client 访问。同一端点也可从 Python 的 gradio_client 访问——一个函数,两个 SDK,无需重复代码。

普通的 @server.get / @server.post 留给静态内容:HTML 页面、文件查找、轻量字典读取。这是 gradio.Server 介绍文章 中的经验法则,也是这三个 UI 迥异的应用保持一致性的原因。

立即体验

上传一份简历、一张 Slack 对话截图、一行带 token 的日志。有趣的部分在于看 Privacy Filter 在你真正关心的文本上能捕捉到(以及偶尔遗漏)什么。

推荐阅读

相似文章

介绍 OpenAI Privacy Filter

OpenAI Blog

OpenAI 发布了 Privacy Filter,这是一个开放权重模型,旨在高效且具有上下文感知地检测和编辑文本中的个人身份信息(PII)。

openai/privacy-filter

Hugging Face Models Trending

OpenAI 发布了 Privacy Filter,这是一个包含 15 亿参数的双向令牌分类模型,用于检测和处理个人身份信息(PII)。该模型采用 Apache 2.0 许可证,并支持长上下文,以实现高通量的数据清理。

OpenAI 隐私过滤模型

Reddit r/LocalLLaMA

OpenAI 悄悄在 Hugging Face 发布了一款 Apache-2.0 授权的隐私过滤模型,权重完全开放,旨在帮用户在本地运行隐私保护过滤器的同时,仍享受大实验室级别的质量。