576. Bengali.AI Speech Recognition | bengaliai-speech
衷心感谢主办方对本次比赛的精心组织。每当有问题出现时,主办方总能及时清晰地回应。我非常享受解决这个问题的过程,在此特别感谢@imtiazprio。
和大多数参赛者一样,我从YellowKing管道开始入手。我将骨干网络替换为IndicWav2Vec,并重新初始化了CTC层。使用这种方法结合公开的Dari/规范化流程,在不使用语言模型的情况下已经能够达到0.48x的分数。然而存在一个严重问题:如果模型训练时间过长,本地WER分数与公共排行榜分数不再匹配。当学习率为3e-5时,在40,000步(批量大小16)就出现了本地过拟合。我怀疑模型开始学习错误音频/标注对之间的关系。
由于标注存在噪声,在后续训练阶段我排除了所有mos分数>2.0的样本,分数达到了0.472。在使用新模型重新标注后,我移除了模型WER>0.5和YellowKing WER>0.5的所有样本。这解决了本地过拟合问题,确保本地改进与更好的公共排行榜分数相关联。我使用8e-5的学习率训练模型210,000步(批量大小16),在不使用语言模型的情况下达到了0.452的分数。
此外,我还使用更大的骨干网络训练了模型。遗憾的是由于时间不足,我未能充分发挥其潜力,但在135,000步后已经达到了0.454的分数。更大模型的学习率必须小得多(1e-5)。
关键收获:
我早期尝试过对不同微调模型的logits取平均值。然而这并不奏效,因为预测结果可能未对齐。即使是相同架构的模型也存在这个问题。在这篇论文中描述了一种方法:拼接不同ASR模型的中间特征,然后添加一个Transformer编码器和CTC层。ASR模型的权重被冻结,仅训练Transformer编码器和CTC层。我将此方法应用于我的微调模型:
关键收获:
我深入思考了语言模型部分,曾考虑将整个问题视为seq2seq问题并使用预训练Transformer作为语言模型。最终我使用了标准的KenLM模型,采用了论坛中分享的数据集(如IndicCorp、SLR、Comp数据)。
在预处理阶段,我严格限定使用训练数据的字符集,因为主办方表示测试数据中不会出现新字符。我将数字、其他语言字符替换为特殊标记,这显著减少了Kaggle环境中的unigram数量瓶颈。最终我使用了0 0 0 2 2剪枝的5-gram模型,增加更多数据在某个点后不再提升性能。
对Kaggle工作流更重要的是:如果使用标准的Wav2Vec2ProcessorWithLM然后移除模型,内存不会被释放。因此我拆解了流程:先计算所有logits并本地存储,然后在解码过程中重新读入。之后我通过decoder.cleanup()干净地移除语言模型再删除解码器。没有这个措施,我根本无法使用集成模型,否则会出现内存不足错误。
关键收获:
我尝试了不同的标点模型和集成方法。最终使用了XLM-Roberta-Large模型,分数提升了约0.02。通过强制模型在最后一个词后输出|或?还能进一步提升性能(+0.002)。