ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Qwen3.5-397B-A17B-singprobe 代码实现详解:从 config.json 到建模代码,读懂 8.13M 参数探针的完整原理

Qwen3.5-397B-A17B-singprobe 代码实现详解:从 config.json 到建模代码,读懂 8.13M 参数探针的完整原理

【免费下载链接】Qwen3.5-397B-A17B-singprobe

项目地址:https://ai.gitcode.com/hf_mirrors/inclusionAI/Qwen3.5-397B-A17B-singprobe
点击查看免费下载

Qwen3.5-397B-A17B-singprobe是一款基于 Qwen3.5-397B-A17B 大模型构建的"内生流式安全护栏"(SingProbe)。它不额外运行独立的安全模型,而是直接复用大模型生成过程中的隐藏状态,在每一个 token 生成的瞬间同步输出三类安全信号:查询意图(8 类意图)、回复不安全程度、幻觉风险——整个探针只有8.13M 参数,带来的解码延迟不足 0.5%。这篇文章带你从 config.json 到建模代码,逐层读懂这个"探针"的完整原理。

📌 一文读懂 SingProbe:什么是"内生流式护栏"

传统的大模型安全方案,通常是在生成结束后再调用一个独立的安全审核模型来判断内容是否合规。这种方式有两个明显短板:延迟高(要等回复生成完才审查)和成本大(多跑一个模型)。

SingProbe 的思路完全不同:

对比项传统独立安全模型SingProbe 探针
运行方式生成完再审查生成中逐 token 打分
额外参数一个完整模型8.13M
解码开销一次完整推理< 0.5%
输出事后结论实时安全分数

从 README.md 中的评测数据可以看到它的实际表现:

  • 查询意图分类(6 个基准):F1 达0.8750,超过 YuFeng-XGuard-Reason-8B 的 0.8714
  • 回复安全分类(8 个基准):F1 达0.8696,超过 Qwen3Guard-Gen-8B-strict 的 0.8604
  • 流式安全检测:R-AUC / T-AUC 达0.9905 / 0.9339,大幅领先 Qwen3Guard-Stream-8B
  • 幻觉检测(6 个基准):AUC 达0.8117,超过 DRIFT 的 0.8000
  • 正常回复误报率:5 个数据集平均仅0.03%

🗂️ 仓库全景:5 个文件讲透全部原理

这个仓库非常精简,全部源码就 5 个文件:

文件作用
README.md模型说明、评测结果、部署方法
config.json探针的超参数配置(结构"蓝图")
configuration_sing_probe.py配置类:把 JSON 变成可用的 Config 对象
modeling_sing_probe.py建模代码:探针的网络结构与前向计算
model.safetensors8.13M 参数权重文件(bfloat16)

下面按"配置 → 建模"的顺序逐个拆解。

📝 逐行解读 config.json:探针的 5 个关键参数

打开 config.json,全文只有 20 多行,但每一行都有讲究:

{ "architectures": ["SingProbeAttnModel"], "model_type": "sing_probe_attn", "hidden_size": 4096, "base_model_layer_ids": [18, 38, 58], "num_attention_heads": 8, "head_dim": 64, "sliding_window": 2048, "num_labels": 10, "base_model_name": "Qwen/Qwen3.5-397B-A17B", "torch_dtype": "bfloat16" }

①architectures/model_type— 声明这是一个注意力版探针(SingProbeAttnModel)。注意 config.json 中的auto_map字段,它告诉 HuggingFace 的AutoConfig/AutoModel去哪里加载对应的 Python 类,这是自定义模型能被"一键加载"的关键。

②hidden_size: 4096— 基座模型 Qwen3.5-397B-A17B 每一层输出的隐藏状态维度。

③base_model_layer_ids: [18, 38, 58]— 这是 SingProbe 最核心的一行:探针只"挂钩"基座模型的第 18、38、58 层的隐藏状态,把三层拼接后作为输入特征,维度变为4096 × 3 = 12288。选中间、中后、靠后的层,是为了同时捕捉浅层的表层语义和深层的语义推理结果。

④num_attention_heads: 8+head_dim: 64— 探针内部使用一个"分组查询注意力"(GQA)结构:8 个 Query 头共享1 个KV 头(KV 投影宽度只有 64)。这正是参数量能压到 8M 的关键技巧。

⑤sliding_window: 2048— 注意力上下文限制在 2048 个 token 的滑动窗口内,避免长对话下注意力开销膨胀。

⑥num_labels: 10— 输出 10 个分数,对应8 个意图类别 + 1 个不安全分数 + 1 个幻觉风险分数(即部署时接口返回的label_0–label_9)。

⚙️ 配置类如何工作:input_size = 12288 是这样算出来的

configuration_sing_probe.py 里定义了两个配置类,对应两种探针架构:

  • SingProbeMlpConfig:MLP 版(两层全连接网络)
  • SingProbeAttnConfig:注意力版(本仓库实际采用的架构)

两者都继承自 transformers 的PretrainedConfig,加载config.json后各字段会自动映射为属性。其中最关键的是 input_size 属性:

@property def input_size(self) -> int: return self.hidden_size * len(self.base_model_layer_ids)

这就是前面算的4096 × 3 = 12288——探针真正接收的特征维度。配置类只负责"描述结构",具体的网络搭建在建模代码中。

🧠 建模代码深度剖析:两套探针架构

modeling_sing_probe.py 是全部 8.13M 参数的来源,包含两个模型类。

架构一:MLP 版——最简单的两层网络

SingProbeMlpModel 的结构非常直白:

12288 维特征 → fc1 (线性层) → GELU 激活 → fc2 (线性层) → 10 个分数

共两个线性层(12288→1024→10),适合作为轻量基线。

架构二:注意力版——本仓库采用的架构

SingProbeAttnModel 才是重头戏。它把探针本身做成了一个微型 Transformer 层,内部流程如下:

第 1 步:三路投影(L72-L75)

  • proj_q:12288 → 512(8 头 × 64 维)
  • proj_k/proj_v:12288 → 64(只有 1 个 KV 头,GQA 技巧)
  • 全部不带 bias,参数更省

第 2 步:因果注意力(L111-L135)

对序列长度超过sliding_window(2048)的输入,会触发 滑动窗口注意力:按窗口切块,每个 token 只看"自己 + 前 2047 个 token",既保证因果性(不看未来 token),又控制计算量;否则直接走scaled_dot_product_attention的因果模式。

第 3 步:残差 + 归一化 + 分类头(L136-L139)

注意力输出 → o_proj 投影 + Query 残差连接 → RMSNorm → classifier → 10 个分数

另外,输入校验函数 会在前向时检查输入维度是否等于 12288,不匹配就直接报错——这是防止"探针和基座模型不配对"的第一道保险。

8.13M 参数到底花在哪?逐行算给你看

按 config.json 的数值逐模块核算:

模块权重形状参数量
proj_q12288 × 5126,291,456
proj_k12288 × 64786,432
proj_v12288 × 64786,432
o_proj512 × 512262,144
RMSNorm512512
classifier512 × 10 + 105,130
合计8,132,106 ≈ 8.13M✅

可以看到,近77% 的参数集中在proj_q这一个矩阵上。相对基座模型的 397B 参数,探针占比约 0.002%——这就是"开销 < 0.5%"的数学来源。

🚀 如何部署:SGLang / vLLM 三行命令接入

SingProbe 通过 SGLang 或 vLLM 的集成分支支持,服务器启动时用--probe-ckpt指定探针 ID 即可(命令来自 README.md):

python -m sglang.launch_server \ --model-path Qwen/Qwen3.5-397B-A17B \ --probe-ckpt inclusionAI/Qwen3.5-397B-A17B-singprobe \ --port 30000

服务每生成一个 token,就会额外返回一个包含label_0–label_9的分数字典,你可以实时拿到该 token 对应的意图、不安全度、幻觉风险三个信号。

⚠️ 注意:探针与基座模型必须成对使用(Qwen/Qwen3.5-397B-A17B+ 本仓库权重),因为探针权重是在这套隐藏状态上训练出来的,换基座模型分数会失真。

💡 小结:这套设计妙在哪

  1. 零额外模型:复用基座已有计算流,只加一层 8.13M 的轻量打分头
  2. GQA 极致省参:8 个 Query 头共享 1 个 KV 头,投影矩阵小到惊人
  3. 流式实时:逐 token 打分,安全审查和生成"同步进行",长对话由 2048 滑动窗口兜底
  4. 一套探针三个任务:意图分类、安全检测、幻觉识别一次前向全出

如果你正在为大模型寻找低延迟的安全方案,这个仓库的 config.json 与 modeling_sing_probe.py 值得精读——不到 200 行代码,就写清了一个生产级流式护栏的全部原理。

【免费下载链接】Qwen3.5-397B-A17B-singprobe

项目地址:https://ai.gitcode.com/hf_mirrors/inclusionAI/Qwen3.5-397B-A17B-singprobe
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进