第29名笔记:如何在公共LB上训练一个达到0.972的单一DeBERTa模型
作者:Yannan Chen
排名:第29名
比赛:PII检测与去除(教育数据)
我真的是一名机器学习新手,这次能够进入银牌区感到非常谦虚。非常感谢所有热心分享想法和代码的人们,包括:@nbroad、@valentinweber、@thedrcat、@emiz6413(tokenization、metric、训练管道),@mpware(高质量外部数据生成),@nischaydnk(Longformer和H2O的替代方案),以及无数讨论帖给我带来的灵感与新思路。
我很感激能成为这次旅程的一部分,并学到很多知识。希望以后能够贡献更多。
▶ 训练参数
- 学习率:2e‑4 ~ 2.5e‑5
- 累计批次大小:8 ~ 16
- 训练轮数:3 ~ 5
- 对无PII文章的采样率:0.4
- O类权重:0.2
- 训练最大长度:3072
- 训练截断步幅:512
- 优化器:AdamW
- 学习率调度:Cosine Annealing
▶ 训练技巧
-
仔细手动划分交叉验证折,使每个折的标签分布几乎相同。
我没有使用 document%4 的方式,而是手动将数据分配到4折,以实现几乎相同的标签分布。特别注意那些同时包含多种稀有标签的文章。
(我的数据划分Notebook:https://www.kaggle.com/code/yannan90/pii-df-fold)
-
去掉 B-/I- 前缀,仅训练 8 个标签。(这是最重要的技巧!!)
使用 13 标签训练的模型在公共 LB 上从未超过 0.96,无论如何调参。检查错误预测时,我发现模型无法理解分配 “B-” 或 “I-” 前缀的逻辑,尤其是人名。于是我去掉标签中的 B-/I- 信息,改用 8 标签训练(在后续处理中再添加 B-/I- 前缀)。此后模型性能显著提升,公共 LB 分数在 0.966 到 0.972 之间,CV 与 LB 的对齐也更好了。该调整还有助于识别过拟合,因为 CV 高(0.98~0.99)的模型往往在 LB 上表现较低(0.95~0.96)。
▶ 后处理(不多)
- 使用阈值 0.9。
- 添加安全 URL 白名单。
- 处理当 “/n” 位于已标记为 ADDRESS 的 token 之间时可能被误标为 ADDRESS 的特殊情况。
- 如上所述添加前缀 “B-” 和 “I-”。
从他人方案中学到但未使用的后处理技巧:
- 删除所有不符合首字母大写、长度为1、包含数字或在黑名单中的 NAME_STUDENT 预测(Mr., Ms., Dr., …)。
- 如果一篇文档中某名字出现多次且其中一次被标记为 PII,则将所有该名字标记为 PII(非常有效)。
- 如果预测的 NAME_STUDENT 前有冠词,除非后面跟着 “'s”,否则删除。
- 将包含 9 位或更多数字的 PHONE_NUM 预测转换为 ID_NUM。
- 使用正则表达式匹配电话号码。
- 删除 “:” 和 “-” 对应的 “B-ID_NUM” 预测。
▶ 最终提交推理策略
- 组合 3 个在不同折上训练的 DeBERTa‑v3‑large 模型,给予在公共 LB 上得分最高(0.972)的模型最大权重。
- 由于训练时使用了不同的 tokenizer,spaCy 的一个 token 不可避免地会被拆分成多个推理 token,从而产生多个预测。在这种情况下,我尝试了三种策略来选择最佳预测:a. 选取第一个预测;b. 选取 O 概率最小的预测;c. 选取正类概率最大的预测。最终选择了策略 c。
(我的提交 Notebook:https://www.kaggle.com/code/yannan90/pii-infer-ensemble-ignorebi)
▶ 经验教训 & 进一步提升
- 使用 llama‑3 70b / mixtral‑8x‑7b 生成外部数据。 提示模型在训练数据中加入针对性内容(链接)。
- 使用改写工具对误报样本进行改写并加入训练集。 如 Dipper Paraphraser XXL。
- 清洗并重新标注训练数据中的错误标签。
- 在分类器前加入 BiLSTM 层: 有助于多样性并使训练曲线更平滑。
- 知识蒸馏: 使用在不同数据集上训练的模型作为教师,对同一验证折的学生进行蒸馏。
- 数据增强: 交换或更改某些文章中的名字。
- 为 tokenizer 添加换行符 token:
tokenizer.add_tokens(["\n", "\n\n"], special_tokens=True)
- 在损失函数中对外部数据使用较低的权重: 训练数据样本权重为 1.0,额外数据样本权重为 0.5。
- 在硬预测时对 O 类概率进行缩放后再取 argmax, 而不是使用 O 概率阈值。
- 通过观察错误 OOF 预测的模式进行更多后处理。
- 多元化模型进行集成:
- a. 使用不同模型类型,尤其是使用不同 tokenizer 的模型。
- b. 训练/推理时带前缀和不带前缀的模型混合。
- c. 训练/推理时使用不同 max_length 的模型组合。
PS:我只提交了 DeBERTa‑v3‑large 的集成,因为它们在 CV 和 LB 上表现最好。现在我知道我的另一个集成(DeBERTa‑v3‑large + Longformer)在私有 LB 上取得了 0.9662(金牌区),但由于 Longformer 在 CV 和 LB 上表现不佳,我没有提交。真是遗憾 LOL!
- 加速集成推理的技巧:
- a. 使用 FP16 进行推理。
- b. 使用 ONNX(链接)。
- c. 动态填充(链接)。
- d. 根据不同 token 长度采用不同的批次大小。
方案参考链接