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/benchmark.py from x6nux/laya-ad: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/x6nux/laya-ad/resolve/main/code/scripts/benchmark.py
- Command line
-
hf download hf://x6nux/laya-ad/code/scripts/benchmark.py
-
curl -L -o benchmark.py https://huggingface.co/x6nux/laya-ad/resolve/main/code/scripts/benchmark.py
3.89 kB
| #!/usr/bin/env python3 | |
| """吞吐基准:测不同 batch × 序列长度 × 精度下的前向吞吐。 | |
| 输出 samples/s、tokens/s、延迟 p50 与显存峰值,用于选训练 batch 和部署配置。 | |
| 输入为随机 token(测的是纯算力上限);真实短文本的收益还要叠加动态 padding, | |
| 见 README「吞吐优化」一节。 | |
| 用法: | |
| python scripts/benchmark.py # seq=128/512 × batch=8..128, bf16 | |
| python scripts/benchmark.py --fp32 # fp32 对照 | |
| python scripts/benchmark.py --compile # 额外测 torch.compile 版本 | |
| """ | |
| import argparse | |
| import time | |
| import torch | |
| from transformers import AutoModelForSequenceClassification | |
| def bench_once(model, x, attn, iters): | |
| for _ in range(3): | |
| with torch.inference_mode(): | |
| model(input_ids=x, attention_mask=attn) | |
| torch.cuda.synchronize() | |
| lat = [] | |
| t0 = time.perf_counter() | |
| for _ in range(iters): | |
| t1 = time.perf_counter() | |
| with torch.inference_mode(): | |
| model(input_ids=x, attention_mask=attn) | |
| torch.cuda.synchronize() | |
| lat.append((time.perf_counter() - t1) * 1000) | |
| total = time.perf_counter() - t0 | |
| return total, lat | |
| def run(model, args, dtype_name, results): | |
| for seq in args.seqs: | |
| for batch in args.batches: | |
| x = torch.randint(1000, 200000, (batch, seq), device="cuda") | |
| attn = torch.ones_like(x) | |
| torch.cuda.reset_peak_memory_stats() | |
| try: | |
| total, lat = bench_once(model, x, attn, args.iters) | |
| except torch.cuda.OutOfMemoryError: | |
| torch.cuda.empty_cache() | |
| print(f"[{dtype_name}] seq={seq:>4} batch={batch:>4} | OOM,跳过") | |
| continue | |
| row = { | |
| "dtype": dtype_name, "seq": seq, "batch": batch, | |
| "samples_per_s": batch * args.iters / total, | |
| "tokens_per_s": batch * args.iters * seq / total, | |
| "p50_ms": sorted(lat)[len(lat) // 2], | |
| "vram_gb": torch.cuda.max_memory_allocated() / 2**30, | |
| } | |
| results.append(row) | |
| print(f"[{row['dtype']}] seq={seq:>4} batch={batch:>4} | " | |
| f"{row['samples_per_s']:>9.1f} 样本/s | " | |
| f"{row['tokens_per_s'] / 1e6:>6.2f}M tok/s | " | |
| f"p50={row['p50_ms']:>7.1f}ms | VRAM={row['vram_gb']:.2f}GB") | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--model", default="models/mmbert-ad") | |
| ap.add_argument("--seqs", type=int, nargs="+", default=[128, 512]) | |
| ap.add_argument("--batches", type=int, nargs="+", default=[8, 32, 64, 128]) | |
| ap.add_argument("--iters", type=int, default=20) | |
| ap.add_argument("--fp32", action="store_true", help="只测 fp32") | |
| ap.add_argument("--compile", action="store_true", help="追加测 torch.compile") | |
| args = ap.parse_args() | |
| results = [] | |
| dtypes = ["fp32"] if args.fp32 else ["bf16"] + (["fp32"] if False else []) | |
| for dt in dtypes: | |
| model = AutoModelForSequenceClassification.from_pretrained( | |
| args.model, attn_implementation="sdpa", | |
| dtype=torch.float32 if dt == "fp32" else torch.bfloat16).eval().cuda() | |
| run(model, args, dt, results) | |
| if args.compile and dt == "bf16": | |
| compiled = torch.compile(model) | |
| print("(torch.compile:每个新 shape 都要重编译,首次会慢)") | |
| run(compiled, args, dt + "-compile", results) | |
| del model | |
| torch.cuda.empty_cache() | |
| if results: | |
| best = max(results, key=lambda r: r["samples_per_s"]) | |
| print(f"\n最佳吞吐配置: {best['dtype']} seq={best['seq']} batch={best['batch']} " | |
| f"-> {best['samples_per_s']:.0f} 样本/s ({best['tokens_per_s'] / 1e6:.2f}M tok/s)") | |
| if __name__ == "__main__": | |
| main() | |