一、背景
NLP中的NER项目, 按顺序采用bert 、albert语言模型进行embeding,都能够正常运行。换用robert模型的时候,产生Bug :CUDA error:device-side assert triggered
二、分析
1、首先cuda报错,那么换成cpu运行,出现:IndexError:index out of range in self,由此可见robert模型在input_ids 进入embeding的时候出现索引的错误
2、仔细思考一下embeding的过程,需要vocab_size和embeding_dims这两个参数,然后 input_ids[N, T]里面的每一个样本的每个token的id索引[vocab_size, embeding_dims]矩阵中的每个embeding向量,所以问题就出现在这个embeding索引上。
3、加入测试代码,遍历整个dataloader,查看每个样本中的token的id值。
import torch
for batch in dataloader:
max_token_ids = torch.max(batch[0], dim=1) # batch[0]取的是input_ids的数[N, T]
结果发现最大的id都超过了roberta模型的vocab_size=8021。
4、问题进一步挖掘为:tokenizer分词出现问题,检查tokenizer的相关代码以及vocab.txt文件路径,均没有发现异常。疑惑就在这里,分词没问题,input_id按道理就应该没问题呀。
5、再仔细想想数据如何进入模型,首先需要加载到内存中,一般来说,都是通过代码生成数据(已在内存中),这种做法不能循环调用这些数据,本项目为了能够循环调用,将数据生成了一个缓存文件,每次调用直接加载到内存,无需通过程序生成。
6、所以数据全部用的是之前模型的缓存数据,检查bert模型的vocab_size=21128,大于8021,也就是说input_ids是bert模型构建的token到id,所以存在大于8021的id
三、解决
1、将缓存文件删掉即可
2、增加模型类型参数,按模型名称生成缓存文件