Text Classification
Transformers
Safetensors
Chinese
spam-detection
advertising-detection
ad-classification
chinese
modernbert
mmbert
multi-task
four-head
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
Download code/scripts/convert_dataset.py from x6nux/laya-ad: direct link, hf CLI and curl.
- Browser
- Download file 4.03 kB
-
https://huggingface.co/x6nux/laya-ad/resolve/main/code/scripts/convert_dataset.py
- Command line
-
hf download hf://x6nux/laya-ad/code/scripts/convert_dataset.py
-
curl -L -o convert_dataset.py https://huggingface.co/x6nux/laya-ad/resolve/main/code/scripts/convert_dataset.py
4.03 kB
| #!/usr/bin/env python3 | |
| """内部反广告数据集清洗转换 → 微调管线格式({"text","label"}+元数据)。 | |
| 修正口径(依据数据集 README + 2026-10-24 实测体检): | |
| 1. verdict=ad 且 ad_kind=none/缺失 → 按生产兜底口径转 clean | |
| 2. 同文本多标注(gold 内实测 157 个矛盾文本)→ 按 quality 优先级取强标注 | |
| (llm_reviewed > manual > rule > hash > so_initial > other),平级取最新 | |
| 3. kind="manual"(23 条,quality 值串入 kind 字段)→ 二分类下照常为 ad; | |
| kind 方案下标为 unspecified | |
| 4. "类型: " 残留复验:实测 3 条均为正常用户内容(对话类型/消息类型等),非标签泄漏 | |
| 5. 空文本剔除;保留 path/quality/ad_kind 元数据供分层采样 | |
| 用法: | |
| python scripts/convert_dataset.py --subset gold # 二分类(默认,生产网关口径) | |
| python scripts/convert_dataset.py --subset gold --label-scheme kind # 细粒度 kind 类别 | |
| python scripts/convert_dataset.py --subset dedup --label-scheme kind | |
| """ | |
| import argparse | |
| import gzip | |
| import json | |
| from collections import Counter | |
| from pathlib import Path | |
| QUALITY_RANK = {"llm_reviewed": 5, "manual": 4, "rule": 3, "hash": 2, "so_initial": 1, "other": 0} | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--src", default="data/raw/dataset/ft") | |
| ap.add_argument("--subset", default="gold", choices=["gold", "dedup", "full"]) | |
| ap.add_argument("--label-scheme", default="binary", choices=["binary", "kind"], | |
| help="binary: normal/ad(生产网关口径); kind: normal + 广告细类") | |
| ap.add_argument("--out", default=None) | |
| args = ap.parse_args() | |
| src = Path(args.src) / f"antiad_ft_{args.subset}.jsonl.gz" | |
| if not src.exists(): | |
| raise SystemExit(f"[ERR] 找不到 {src}") | |
| out = args.out or f"data/raw/dataset/converted/{args.subset}.{args.label_scheme}.jsonl" | |
| out = Path(out) | |
| out.parent.mkdir(parents=True, exist_ok=True) | |
| stat = Counter() | |
| best = {} # text -> (quality_rank, time, row) | |
| with gzip.open(src, "rt", encoding="utf-8") as f: | |
| for line in f: | |
| r = json.loads(line) | |
| stat["读入"] += 1 | |
| text = (r.get("text") or "").strip() | |
| if not text: | |
| stat["丢弃:空文本"] += 1 | |
| continue | |
| verdict, kind = r["verdict"], r.get("ad_kind") | |
| if verdict == "ad": | |
| if not kind or kind == "none": | |
| stat["修正:ad+kind_none→clean"] += 1 | |
| verdict = "clean" | |
| elif kind == "manual": | |
| stat["修正:kind_manual→unspecified"] += 1 | |
| kind = "unspecified" | |
| if verdict == "clean": | |
| label = "normal" | |
| elif args.label_scheme == "binary": | |
| label = "ad" | |
| else: | |
| label = kind or "unspecified" | |
| row = {"text": text, "label": label, "path": r["path"], | |
| "quality": r["quality"], "ad_kind": kind, "id": r["id"]} | |
| rank = QUALITY_RANK.get(r["quality"], 0) | |
| prev = best.get(text) | |
| if prev is None: | |
| best[text] = (rank, r["time"], row) | |
| else: | |
| stat["去重:同文本取强标注"] += 1 | |
| if (rank, r["time"]) > (prev[0], prev[1]): | |
| best[text] = (rank, r["time"], row) | |
| rows = sorted((b[2] for b in best.values()), key=lambda x: x["id"]) | |
| with open(out, "w", encoding="utf-8") as f: | |
| for row in rows: | |
| f.write(json.dumps(row, ensure_ascii=False) + "\n") | |
| labels = Counter(r["label"] for r in rows) | |
| paths = Counter(r["path"] for r in rows) | |
| print(f"[OK] {src.name} -> {out} ({len(rows)} 行)") | |
| print("清洗统计:", dict(sorted(stat.items()))) | |
| print("label 分布:", dict(labels.most_common())) | |
| print("path 分布:", dict(paths.most_common())) | |
| if __name__ == "__main__": | |
| main() | |