Instructions to use x6nux/laya-ad with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use x6nux/laya-ad with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="x6nux/laya-ad")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("x6nux/laya-ad", device_map="auto") - Notebooks
- Google Colab
- Kaggle
laya-ad v2.2 · 四头广告识别(二分类 + 7 类 kind + scope + severity)
基于 Laya(mmBERT / ModernBERT,322M,Apache-2.0)的单模型四头结构:一次前向同时输出
- 二分类:
ad/normal - 7 类 kind:
crypto/gambling/porn/porn_bait/promo/scam/spam_flood - scope:
account(账号本身是广告号)/message(仅这条消息是广告;非广告也归 message) - severity:0–3(harmless / mild promotion / clear traffic-driving / scam, explicit porn or mass flooding)
v2.2 相对 v2.1 的变化:训练数据合入 gmeow 封禁广告语料 880 条(真实封禁账号的推广文本,jev-1.13 实时判定,含 kind/scope/severity 标签),其中 752 条进训练池、128 条留出作独立测试切片。gmeow 带来了大量「account 型广告号」载体(此号不回复 || 主号@xx + 双向机器人 + 课表频道)和 scam/promo/porn 的新边界样本。
仍是一个模型:六个精度目录(fp32/ fp16/ bf16/ fp8/ int8/ int4/)是同一个模型的不同存储精度;版本由 git tag v2.2 承载,目录结构不变。v2.1(teacher 数据四头)和 v2/v1.1 保留在旧 tag。
架构
text ──> 共享 ModernBERT encoder (322M)
├─ binary head → ad / normal
├─ kind head → 7 类
├─ scope head → account / message
└─ severity head → 0..3(期望分数 score=Σi·p_i)
- 共享编码器 + 四个任务头,309.3M 参数。
- 四头联合训练:binary 加权损失 + 广告过采样到 22.4%,kind/severity 类别加权,scope/severity 头只学广告(normal 交给二分类 gate)。
标签
- binary:
0 = ad、1 = normal - kind:
crypto, gambling, porn, porn_bait, promo, scam, spam_flood - scope:
account, message - severity:
0 harmless, 1 mild promotion, 2 clear traffic-driving, 3 scam/explicit porn/mass flooding - 建议
max_length384。
指标说明(表格里每个数是什么)
测试集
| 测试集 | 条数 | 其中广告 | 标签来源 | 用途 |
|---|---|---|---|---|
| teacher holdout | 2,732 | 64 | jev-1.13 teacher 全请求体判定 | 检验与 teacher 分布的一致性;广告太少,指标波动大 |
| earlier val | 2,927 | 685 | 早期生产 v1 模型判定 | 广告样本量最大,kind/scope 指标最可靠 |
| gmeow_val128 | 128 | 128 | jev-1.13 对真实封禁账号的判定 | 全新封禁广告切片(v2.1 完全没见过),专测 gmeow 语料带来的增益 |
三个测试集的标签都来自模型/teacher 而非人工标注,所以所有指标的正确读法是「与对应标签的一致率」,不是绝对正确率;三组标签来源不同,数值之间也不能直接横向比较。
指标
| 指标 | 定义 | 怎么读 |
|---|---|---|
| binary accuracy | 全部样本上二分类(ad/normal)判对的比例 | 正常样本占多数,"全判正常"也能刷高这个数——所以必须配合下面的广告 F1 看 |
| 广告 F1 | 只看"广告"这一类的 precision / recall 调和平均 | 衡量抓广告的综合能力:漏放广告(FN)和误伤正常消息(FP)都算错;越接近 1 越好 |
| kind accuracy | 已确认是广告的样本里,7 类细类判对的比例 | 反映"是什么类型的广告"判断得准不准 |
| kind core-F1 | 7 类中样本充足的 5 个核心类(crypto/gambling/porn/promo/scam)的宏平均 F1 | 排除 porn_bait/spam_flood(样本太少会让指标抖动),比 kind accuracy 更稳定 |
| scope accuracy | 广告样本上区分 account(账号本身是广告号)/ message(仅这条消息是广告)的准确率 |
直接对应处置动作:account → 封号,message → 删消息 |
| severity 期望 MAE | severity 头输出 0–3 四档概率,取期望分数 Σi·pᵢ,与标签等级的平均绝对误差 | 0.35 ≈ 平均偏差约 1/3 个等级;用期望分数而不是 argmax,因为 0–3 是有序等级(判 2 错标 3 只差一级,判 0 错标 3 差三级) |
| 与 fp32 一致率(binary/kind) | 量化变体在相同样本上与 fp32 做出相同二分类 / kind 判定的比例 | 衡量量化损失,不是正确率——fp32 本身也可能错;int4 的 kind 一致率明显低,细类敏感场景避免 int4 |
| 体积 | 各精度目录 model.safetensors 的文件大小 |
决定下载时长与内存占用;fp8/int8 约 295MB 适合 CPU/小内存部署 |
四个头分别用于什么决策
| 头 | 输出 | 生产用途 |
|---|---|---|
| binary | ad / normal | 要不要拦这条消息 |
| kind | 7 类 | 广告是什么类型(决定公示、上报、策略) |
| scope | account / message | 封号还是只删消息 |
| severity | 0–3 期望分数 | 严重程度分级(3 = 诈骗/ explicit 色情/大规模刷屏) |
性能(fp32 基准;gmeow_val128 为 bf16 实测)
测试集与指标定义见上方「指标说明」;三组标签来源不同,不能直接横向比较,指标应理解为「与对应标签的一致率」。
| 指标 | teacher holdout | earlier val | gmeow_val128 |
|---|---|---|---|
| binary accuracy | 98.87% | 96.99% | 96.88% |
| 广告 F1 | 0.735 | 0.937 | 0.984 |
| kind accuracy / core-F1 | 77.59% / 0.695 | 95.47% / 0.923 | 79.69% / 0.825 |
| scope accuracy(广告) | 93.75% | 96.08% | 94.53% |
| severity 期望 MAE(0–3) | 0.352 | 0.476 | 0.122 |
v2.2 vs v2.1(同口径 bf16 对比)
| 测试集 | 指标 | v2.1 | v2.2 |
|---|---|---|---|
| earlier val(广告 685) | binary acc | 96.34% | 97.03% |
| 广告 F1 | 0.926 | 0.938 | |
| kind acc | 91.37% | 95.47% | |
| severity MAE | 0.534 | 0.475 | |
| gmeow_val128(广告 128) | 广告 F1 | 0.980 | 0.984 |
| kind acc | 67.19% | 79.69% | |
| scope acc | 64.84% | 94.53% | |
| severity MAE | 0.269 | 0.122 | |
| teacher holdout(广告 64) | binary acc | 99.16% | 98.87% |
| 广告 F1 | 0.803 | 0.735 | |
| kind acc | 86.21% | 75.86% |
teacher holdout 只有 64 条广告、58 条 kind,2 条翻转即是 ~3pt 波动;v2.1 在 teacher 数据分布上训练,天然贴近该切片。在两个更大的测试集(earlier val、gmeow_val128)上 v2.2 全面占优。
精度变体(teacher holdout)
| 子目录 | binary acc | 广告 F1 | kind acc / core | scope | severity MAE | 与 fp32 一致率(binary/kind) | 体积 |
|---|---|---|---|---|---|---|---|
fp32/ |
98.87% | 0.735 | 77.59% / 0.695 | 93.75% | 0.352 | — | 1180 MB |
fp16/ |
98.87% | 0.735 | 75.86% / 0.691 | 93.75% | 0.351 | 100.00% / 98.28% | 590 MB |
bf16/ |
98.87% | 0.735 | 75.86% / 0.691 | 93.75% | 0.352 | 100.00% / 98.28% | 590 MB |
fp8/ |
98.87% | 0.748 | 75.86% / 0.692 | 93.75% | 0.358 | 99.63% / 98.28% | 295 MB |
int8/ |
98.76% | 0.721 | 75.86% / 0.691 | 93.75% | 0.352 | 99.82% / 98.28% | 296 MB |
int4/ |
98.50% | 0.692 | 74.14% / 0.669 | 90.62% | 0.324 | 99.05% / 91.38% | 157 MB |
earlier val 上 fp32/bf16 的 kind acc 95.47%、广告 F1 0.937/0.938;int4 的 kind 降到 92.11%(kind 一致率 94.44%)。对细类精度敏感时用 bf16/fp16/fp32。
快速开始
import sys
import torch
from huggingface_hub import snapshot_download
from transformers import AutoTokenizer
path = snapshot_download("x6nux/laya-ad", revision="v2.2",
allow_patterns=["bf16/*", "code/scripts/*"])
sys.path.insert(0, f"{path}/code/scripts")
from dual_head_model import load_dual_head_any
sub = f"{path}/bf16" # fp32 / fp16 / bf16 / fp8 / int8 / int4
tok = AutoTokenizer.from_pretrained(sub)
model = load_dual_head_any(sub, device="cpu", dtype=torch.bfloat16)
texts = ["日入500+,宝妈学生均可,私聊领教程", "今晚八点开会,记得带电脑"]
enc = tok(texts, truncation=True, max_length=384, padding=True, return_tensors="pt")
with torch.inference_mode():
blog, klog, slog, vlog, _ = model.forward_all(enc["input_ids"], enc["attention_mask"])
p_ad = torch.softmax(blog.float(), -1)[:, 0]
p_kind = torch.softmax(klog.float(), -1)
p_scope = torch.softmax(slog.float(), -1)
p_sev = torch.softmax(vlog.float(), -1)
severity_score = (p_sev * torch.arange(4)).sum(1)
命令行:
cd code/scripts
python predict_dual_head.py --model ../../bf16 --text "日入500+,宝妈学生均可,私聊领教程"
输出包含 is_ad、p_ad、kind、kind_probs、scope、scope_probs、severity_score、severity_probs。
Jev API 路由
laya-server 按 criteria 自动选择头:
| 请求 | 输出 |
|---|---|
choice {ad, clean} |
二分类概率 |
choice 含 none + 7 kind |
8 类概率(none=p_clean,kind_i=p_ad×p_kind_i) |
choice {account, message} |
scope 概率 |
score 4 档 severity |
4 类概率 + score=Σi·p_i |
训练
- 数据:teacher 清洗数据 + 早期数据合并去重,再合入 gmeow 封禁广告 752 条(另 128 条留出测试,同文本从 teacher/earlier 池剔除防泄漏)。
- train 101,746 条,广告过采样到 22.4%;kind 每类最少 1,000;severity 0/1 补齐到 500/1,000。
- 初始化沿用 v2 低学习率双头模型,四头联合训练 3 epochs(encoder lr 5e-6 / head lr 2e-4,OneCycleLR)。
- 训练脚本见
code/scripts/train_multi_head.py;数据构建见code/scripts/build_optimized_dataset.py(--gmeow)。
已知限制
- 没有独立人工真值:teacher holdout / earlier val / gmeow 的标签本身来自 jev-1.13 或 v1 判定,绝对正确率无法测量;表中的指标是"与对应标签的一致率"。
- teacher holdout 广告只有 64 条、kind 58 条,小指标波动大。
- gmeow_val128 仅 128 条,scope/kind 的提升幅度(+29.7pt / +12.5pt)受单切片影响,宜与 earlier val 的 kind +4.1pt 互证。
porn_bait/spam_flood样本仍少;scam ↔ promo边界混淆仍在(gmeow 已补充部分样本)。- severity 是 0–3 有序等级,建议看期望 MAE,不要只看 argmax accuracy。
- int4 的 kind/scope 有可见下降(kind 一致率 91.38%);对细类精度敏感时避免 int4。
版本
v2.2(main,本页):四头模型 + gmeow 语料,六精度目录。v2.1(历史 tag):四头模型(teacher 数据)。v2(历史 tag):二头(binary + kind)。v1.1(历史 tag):纯二分类。- GitHub:x6nux/laya-ad
Model tree for x6nux/laya-ad
Base model
convaiinnovations/laya-multilingual