#!/usr/bin/env python3 """标记形态增广(仅训练用)。 背景:生产文本里的结构性标记有多种写法——全角方括号 [引用](训练数据原始形态)、 【引用】、[quoted]、…。模型若只在单一形态上训练,换写法会产生 OOD 漂移。 做法:训练时以概率 p 把 [中文名] 随机改写成其它形态,让模型对"标记怎么写"不敏感, 从而**推理端不需要任何归一化预处理**。实测(827 条干净 holdout,v2b 模型): 6 种形态下 acc 99.64~99.76%、广告召回 99.12~99.56%,未归一化即可直接用。 """ import random import re # 规范中文标记 → 英文别名(增广时用来生成 xml/半角写法) EN_NAME = { "引用": "quoted", "图片": "image", "贴纸": "sticker", "转发自": "forwarded_from", "预览": "preview", "隐藏链接": "hidden_link", "按钮": "button", "文件": "file", "联系人卡片": "contact_card", "访客bot": "guest_bot", "音频": "audio", "故事": "story", "清单": "list", "经由": "via", "入群资料检查": "join_check", "前置号复核": "prewarm_check", "富消息": "rich_message", "视频": "video", "投票": "poll", "地点": "location", } STYLES = ("xml_en", "bracket_half", "lenticular") _FLAG = re.compile(r"[([^]\n]{1,16})]") def augment_markers(text: str, rng: random.Random, p: float = 0.5) -> str: """以概率 p 把规范标记 [中文名] 改写成 xml / 半角 / 方头形态之一。""" if not text or "[" not in text or rng.random() >= p: return text style = rng.choice(STYLES) def repl(m: re.Match) -> str: canon = m.group(1) en = EN_NAME.get(canon) if style == "xml_en": return f"<{en}>" if en else m.group(0) if style == "bracket_half": return f"[{en or canon}]" return f"【{canon}】" return _FLAG.sub(repl, text) if __name__ == "__main__": for p in (0.0, 1.0): for style_seed in range(3): rng = random.Random(style_seed) rng.random = lambda: 0.0 # 强制触发,便于观察 print(f"p={p} ->", augment_markers( "领388\n[引用]广告内容\n[图片]二维码", random.Random(style_seed), p))