fastnlp / fastNLP

fastNLP: A Modularized and Extensible NLP Framework. Currently still in incubation.
https://gitee.com/fastnlp/fastNLP
Apache License 2.0
3.06k stars 450 forks source link

RuntimeError: CUDA error: device-side assert triggered #287

Closed caobocong closed 4 years ago

caobocong commented 4 years ago

Describe the bug 用Predictor方法去加载训练好的模型,在预测时会出现第一张图里面的错误,这个bug被我fixed了。详细请见我在下文上传的项目链接。 出现原因:经过debug分析,发现此bug是由于预测新数据时出现了训练时候没有的新字符,而在bert_embedding.py 脚本里面读取的是训练时候的Vocab维度,并把它初始化成1的vocab向量做mask预测,而这导致了此向量的维度小于实际维度,实际维度=训练时候的Vocab维度+新字符的维度。 Bug结果请看图一,Bug位置及修复请看图二。 image

image

To Reproduce 1.把test.txt、dev.txt、train.txt移到data目录下。data目录为自己创建的目录

  1. 调用fastNLP_trainer.py脚本
  2. 调用fastNLP_predictor.py脚本
  3. See error 重现这个bug的步骤

项目链接:https://github.com/Chris-cbc/fastNLP_Bug_Report_And_Fix.git

Expected behavior image 上图也是bug修复后出现的结果

Desktop

Additional context 请项目主确认后 发邮件并at我github账户一下,让我知道这个bug最终是怎样被修复的 备注

onebula commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

yhcc commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

caobocong commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

我确实是按你说的这样做的,fastNLP_predictor.py里面有代码。也就是保存了训练时候的vocab在vocab.json里面,然后预测时用这个vocab.json里面的内容去index将要被predict的文本。但是此bug与这些操作无关,它是由于读取保存的模型时使用了这个模型训练时候留下的vocab词汇,然后在调用Predictor方法时就直接读取了模型缓存里面vocab,所以不管你后来怎么对新数据进行vocab的index操作,它都无法影响已经在缓存里面的vocab维度,除非能把我保存下来的vocab直接传进Predictor里面然后优先被使用

caobocong commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

和unknown的无关吧

yhcc commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

和unknown的无关吧

有关,如果这个词没有在训练的时候见过,会被指定为unknown的index。如果需要使用之前训练的model,需要同时把当时的vocab存下来,然后用存下来的vocab去index新的数据,再用model预测。

caobocong commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

和unknown的无关吧

有关,如果这个词没有在训练的时候见过,会被指定为unknown的index。如果需要使用之前训练的model,需要同时把当时的vocab存下来,然后用存下来的vocab去index新的数据,再用model预测。

关键就在这最后一步:“然后用存下来的vocab去index新的数据” 目前Predictor会通过buffer方法加载保存在模型里面的vocab,不会使用你存下来的vocab,所以它才是个bug

yhcc commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

和unknown的无关吧

有关,如果这个词没有在训练的时候见过,会被指定为unknown的index。如果需要使用之前训练的model,需要同时把当时的vocab存下来,然后用存下来的vocab去index新的数据,再用model预测。

关键就在这最后一步:“然后用存下来的vocab去index新的数据” 目前Predictor会通过buffer方法加载保存在模型里面的vocab,不会使用你存下来的vocab,所以它才是个bug

就自己保存的vocab和model的vocab会是同一个呀。

caobocong commented 4 years ago

个人理解,你得保存训练时的vocab,然后predict的时候先index一遍,这样训练时未出现过的就是unknown了

是的,必须要用训练的时候的词表去index数据。

和unknown的无关吧

有关,如果这个词没有在训练的时候见过,会被指定为unknown的index。如果需要使用之前训练的model,需要同时把当时的vocab存下来,然后用存下来的vocab去index新的数据,再用model预测。

关键就在这最后一步:“然后用存下来的vocab去index新的数据” 目前Predictor会通过buffer方法加载保存在模型里面的vocab,不会使用你存下来的vocab,所以它才是个bug

就自己保存的vocab和model的vocab会是同一个呀。

你试着按我写的reproduce这个bug的步骤来重现一下这个bug

yhcc commented 4 years ago

https://github.com/Chris-cbc/fastNLP_Bug_Report_And_Fix/blob/295aade0baec49232291625b29f34e45be9c2c12/fastNLP_predictor.py#L128 这一步会将之前没有的word新加入到vocab中,而这个词并不存在与之前的model中,直接删掉这一句应该就可以运行了。