encoder-guard / README.md
louivis's picture
legal: 正文许可章节与 frontmatter 对齐
a9c40db verified
|
Raw History Blame Contribute Delete
9.85 kB
---
license: other
license_name: encoder-guard-non-commercial-1.0
license_link: https://huggingface.co/louivis/encoder-guard/blob/main/LICENSE
base_model: Qwen/Qwen3Guard-Stream-0.6B
library_name: verdict
pipeline_tag: text-classification
language:
- zh
- en
tags:
- content-moderation
- safety
- text-classification
- encoder
- qwen3
- bidirectional
- tc260
- pii
extra_gated_heading: 申请访问 Encoder-Guard 模型
extra_gated_prompt: >-
本模型为**分组件许可**作品:backbone 权重适用 Apache-2.0(源自 Qwen),
分类头与训练产物适用 Encoder-Guard Non-Commercial License 1.0(禁止商业使用)。
请说明具体用途与部署场景,审批通常在 3 个工作日内完成。
完整条款见仓库内 LICENSE 与 LICENSE-APACHE-2.0。
extra_gated_fields:
Name: text
Organization: text
Email: text
Intended use: text
Deployment scenario: text
"I agree to use this model for non-commercial use ONLY": checkbox
"I will retain the Apache license text when redistributing": checkbox
extra_gated_button_content: 提交访问申请
extra_gated_description: 提交后请等待人工审批,审批结果会通过邮件通知。
---
# Encoder-Guard v3 (v3-2026.10.25)
判别式内容安全分类器。**一次前向**输出文本的完整安全画像:整体违规判定 + 四套分类体系
(TC260 / 大模型安全 / 个人信息 / 数据分级)共 11 个分类头。
> ⚠️ **这是分类器,不是 chat 模型。** 不支持 Ollama / vLLM / llama.cpp 的 chat 或 generate 接口,
> 也不产出自然语言。请用 [verdict](https://github.com/vislee/verdict) 引擎或自行实现前向。
## v3 是什么
**v3 = v2 的权重 + fp16 域重校准阈值。** 权重文件与 v2 逐字节相同(sha256 一致),
唯一差异是 `threshold.json` 中的 `safety_threshold`:
| | v2 | **v3(本版本)** |
|---|---|---|
| `safety_threshold` | 0.9664045572280884 | **0.96630859375** |
| 校准域 | fp32 推理输出 | **fp16 推理输出** |
| 校准集 | calib_v23_independent (9394) | 同左 |
| 校准结果 | FPR 2.00% / recall 0.9017 | **FPR 1.95% / recall 0.9017** |
**为什么需要重校准**:v2 的阈值是在 fp32 推理输出上标定的,但发布包是 fp16 权重。
fp16 加载后精确位展开为 F32,数值与 fp32 包有 1e-6 量级差异,落在阈值边界附近的样本
会翻转判定。v3 用 fp16 域的实际输出重新标定,消除这个域偏移。
**v2 与 v3 的实测差异**(v6_35 test 3840 条,见下方评测):AUROC、Recall@FPR≤2%、
各轨 F1 完全一致;校准阈值下 recall 从 0.8354 微升至 0.8382(+0.28pp),FPR 与灰区率不变。
差异极小但方向正确——**新部署建议直接用 v3**。
## 与 v1 的差异
| | v1 | v2 / **v3** |
|---|---|---|
| 基座 | Qwen2.5-0.5B | **Qwen3Guard-Stream-0.6B** |
| 架构 | Qwen2Model, hidden 896, 24 层 | **Qwen3Model, hidden 1024, 28 层** |
| 分类头 | 10 | **11**(新增 `safety_release` 放行闸门) |
| 权重精度 | fp32 | **fp16**(体积减半,加载时精确位展开为 F32) |
| 训练数据 | v6_8 | **v6_35**(28906 train / 1595 val) |
## 架构
```
输入文本 (≤512 tokens)
│ tokenizer (Qwen3, vocab 151936)
▼
Qwen3Guard-Stream-0.6B backbone(去 causal mask → 全可见双向注意力,无 KV cache)
│ final RMSNorm → mean-pool
▼
共享 FFN → 11 个分类头(sigmoid,logit 域阈值判定)
```
关键改造:**去掉 causal mask**(`is_decoder=false`, `use_cache=false`),
使每个 token 都能看到全序列;**mean-pool 后接分类头**,答案空间封闭(~160 个固定标签位),
不需要语言生成能力。
## 11 个分类头
| 轨道 | 头 | 维度 | 体系 |
|---|---|---|---|
| 整体判定 | `safety` | 1 | logit 域阈值(规避 sigmoid 饱和) |
| 放行闸门 | `safety_release` | 1 | 可放行置信度,`release_gate=0.9416` |
| 内容安全 | `tc260_major` / `tc260_minor` | 5 / 31 | TC260-003《生成式人工智能服务安全基本要求》附录 A |
| 大模型安全 | `lm_major` / `lm_minor` | 10 / 54 | LM01–LM10 大模型安全检测项 |
| 个人信息 | `pii_major` / `pii_minor` | 7 / 10 | GB/T 35273-2020(头出数字码 1–10) |
| 数据分级 | `dc_type` / `dc_level` / `dc_minor` | 4 / 3 / 36 | GB/T 43697-2024(4 大类 + 核心/重要/一般 + 36 子类) |
## 三版本同集评测
测试集:`data/finetune_final_v6_35_test.jsonl`,**3840 条**(unsafe 2485 / safe 1355)。
有标注子集:tc260 2211 / lm 1623 / pii 533 / dc 1979。
引擎:`verdict --batch`(Metal 后端,Apple M4 Max)。复现:`python3 tools/eval_jev/eval_v1_v2_v3.py`
### safety 轨
| 版本 | AUROC | Rec@FPR≤2% | thr@FPR2 | 校准 thr | FPR | Recall | 灰区率 |
|---|---|---|---|---|---|---|---|
| v1 | 0.9302 | **0.0000** | — | 1.0000 | 5.61% | 73.24% | 17.42% |
| v2 | 0.9753 | 0.5759 | 0.9704 | 0.9664 | 3.25% | 83.54% | 5.09% |
| **v3** | **0.9753** | **0.5759** | 0.9704 | 0.9663 | 3.25% | **83.82%** | 5.09% |
**v1 的 Rec@FPR≤2% 为 0 是真实结果,不是计算错误**:v1 输出严重饱和,
2485 个正例中 1616 个、1355 个负例中 60 个都卡在 1.0,任何阈值下 FPR 都 ≥4.4%,
无法满足 ≤2% 约束。这是 v1 被 v2 取代的核心原因之一。
### 分类轨
| 轨 | 版本 | n | acc | micro F1 | macro F1 |
|---|---|---|---|---|---|
| TC260 major (5 类) | v1 | 2211 | 0.8304 | 0.8528 | 0.8280 |
| | v2 | 2211 | 0.8734 | 0.8946 | 0.8771 |
| | **v3** | 2211 | **0.8734** | **0.8946** | **0.8771** |
| LM major (10 类) | v1 | 1623 | 0.6445 | 0.7752 | 0.5753 |
| | v2 | 1623 | 0.6587 | 0.7805 | 0.6133 |
| | **v3** | 1623 | **0.6587** | **0.7805** | **0.6133** |
| PII major (7 类) | v1 | 533 | 0.5028 | 0.6158 | 0.6535 |
| | v2 | 533 | 0.5009 | 0.6158 | 0.6557 |
| | **v3** | 533 | **0.5009** | **0.6158** | **0.6557** |
| DC level (3 类) | v1 | 1979 | 0.9318 | — | 0.7632 |
| | v2 | 1979 | 0.9247 | — | 0.7400 |
| | **v3** | 1979 | **0.9247** | — | **0.7400** |
v2 与 v3 在分类轨上完全一致(权重相同,仅阈值不同,分类轨用 argmax 不受阈值影响)。
## 文件
| 文件 | 说明 |
|---|---|
| `backbone/model.safetensors` | Qwen3Guard-Stream-0.6B backbone,fp16,1.1 GB |
| `backbone/config.json` | 架构配置(`is_decoder=false`) |
| `backbone/tokenizer.json` | Qwen3 tokenizer(vocab 151936) |
| `heads.safetensors` | 11 个分类头权重,fp32,652 KB |
| `threshold.json` | 阈值 + per-head temperature + ECE(**v3 唯一与 v2 不同的文件**) |
| `model_config.json` | 头维度声明 |
| `data_card.json` | 训练数据与超参记录 |
| `train_log.jsonl` | 20 epoch 训练日志 |
## 使用
```bash
# 1. 拉取权重(HF / ModelScope / GitHub Release 自动回退)
hf download louivis/encoder-guard --repo-type model --revision v3-2026.10.25 \
--local-dir model/encoder-guard-v3
# 2. 构建引擎
git clone https://github.com/vislee/verdict && cd verdict && make
# 3. 推理
./verdict -m model/encoder-guard-v3 -t "要审核的文本" --text
./verdict -m model/encoder-guard-v3 --batch input.jsonl --batch-out pred.jsonl
```
`--batch` 输入 JSONL 每行需含 `"prompt"` 键(写 `"text"` 会静默输出空文件)。
## 校验
```
sha256(backbone/model.safetensors) = 383042c91f07dd7bb3d9fccddacd6d20c4bc9e0166bfaa2141bcefb1bbc7436a
sha256(heads.safetensors) = 7549e611eaa8c44e4fe5b034b0059b31b660311f1c92a6ca08e72f00a6e09c85
sha256(threshold.json) = b4ebfc837e5f0d1b6a0b834997ee69e342a1504dd1d1b98799ea0e234a0a52eb
```
backbone 与 heads 的 sha256 与 v2 完全相同(同一份权重)。
## 已知限制
- **最大 512 token**,超长截断(不报错)。
- **空输入 / 极短输入**:`n_tokens=0` 时输出 `prob=nan` 且仍判 `safe`,调用方需自行拦截空串。
- **`dc_type` 较弱**(macro F1 0.67),4 大类边界模糊,建议只作参考不作硬判定。
- **PII 轨** acc 约 0.50,属协议瓶颈(多标签样本只取 argmax 单标签)而非模型退化。
- 训练数据含中文互联网语料,**对非中英文语种的泛化未验证**。
## 许可与归属
本模型为**分组件许可**作品,不同组成部分适用不同条款(完整条款见仓库内 `LICENSE`):
| 组成部分 | 文件 | 许可 |
|---|---|---|
| backbone 权重 | `backbone/model.safetensors`、`tokenizer.json` 等 | **Apache-2.0**(源自 Qwen) |
| 分类头与训练产物 | `heads.safetensors`、`threshold.json`、`model_config.json` 等 | **Encoder-Guard Non-Commercial License 1.0**(禁止商业使用) |
| 模型卡与文档 | `README.md` 等 | CC BY-NC 4.0 |
- 基座:[Qwen/Qwen3Guard-Stream-0.6B](https://huggingface.co/Qwen/Qwen3Guard-Stream-0.6B)(Apache-2.0)
- 修改内容:去除 causal mask 改为双向注意力、移除 KV cache、mean-pool 后接 11 个分类头、
backbone 量化为 fp16。原始基座的生成式 LM head 未使用。
- 推理引擎:[verdict](https://github.com/vislee/verdict)(MIT)
依据 Apache-2.0 第 4 条,本模型作为衍生作品分发时随附 `LICENSE-APACHE-2.0` 全文,
并保留上述声明与修改说明(第 4(a)(b) 条)。分类头与训练产物另受非商业条款约束。
**商业授权**:如需商业使用,请通过 [Hugging Face @louivis](https://huggingface.co/louivis)
或 [GitHub Issues](https://github.com/vislee/verdict/issues) 联系作者取得书面授权。
## 引用
```bibtex
@misc{encoder-guard-v3,
title = {Encoder-Guard v3: Discriminative Content Safety Classifier (fp16 recalibrated)},
author = {Lee, Louivis},
year = {2026},
note = {Qwen3Guard-Stream-0.6B backbone, 11 classification heads},
url = {https://huggingface.co/louivis/encoder-guard}
}
```