Encoder-Guard v3 (v3-2026.10.25)
判别式内容安全分类器。一次前向输出文本的完整安全画像:整体违规判定 + 四套分类体系 (TC260 / 大模型安全 / 个人信息 / 数据分级)共 11 个分类头。
⚠️ 这是分类器,不是 chat 模型。 不支持 Ollama / vLLM / llama.cpp 的 chat 或 generate 接口, 也不产出自然语言。请用 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 训练日志 |
使用
# 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(Apache-2.0)
- 修改内容:去除 causal mask 改为双向注意力、移除 KV cache、mean-pool 后接 11 个分类头、 backbone 量化为 fp16。原始基座的生成式 LM head 未使用。
- 推理引擎:verdict(MIT)
依据 Apache-2.0 第 4 条,本模型作为衍生作品分发时随附 LICENSE-APACHE-2.0 全文,
并保留上述声明与修改说明(第 4(a)(b) 条)。分类头与训练产物另受非商业条款约束。
商业授权:如需商业使用,请通过 Hugging Face @louivis 或 GitHub Issues 联系作者取得书面授权。
引用
@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}
}