danliu2 / caat

MIT License
34 stars 2 forks source link

text-to-text模型推理时鬼畜 #13

Closed dearchill closed 2 years ago

dearchill commented 2 years ago

@danliu2 按照您的建议我重新训练了模型,在使用simuleval的时候遇到了翻译鬼畜的问题,使用的agent是text_fullytransducer_agent,我初步定位到翻译重复的地方是transducer_searcher文件里面infer函数内,在第一次调用self.searcher.search后产生的。 我打印了调用前后prev_tokens的tensor如下:

待翻译tokens:tensor([ 77, 73, 22, 146]) prev_tokens前:tensor([[0]], device='cuda:0') prev_tokens后:tensor([[ 0, 14, 82, 45, 117, 14, 82, 45, 117, 24, 14, 82, 45, 117, 24, 14, 82, 45, 117, 24]], device='cuda:0')

待翻译tokens:tensor([ 72, 360, 31, 731]) prev_tokens前:tensor([[0]], device='cuda:0') prev_tokens后:tensor([[ 1, 1, 1, 0, 11, 4, 165, 1094, 11, 4, 165, 1094, 11, 4, 165, 1094, 11, 4, 165, 1094]], device='cuda:0')

这里prev_tokens的bos_token已经指定了0而不是2,search和search_at函数里面我也没找到原因,不确定是模型本身的问题还是解码时产生的问题,如您空闲的话能帮忙定位一下吗,谢谢!

danliu2 commented 2 years ago

是只在过短的数据上有这种现象还是长的数据也会重复翻译?看上去有点像模型走到最后仍然不输出EOS符号导致循环解码,可以调试观察一下循环开始时的bos和eos输出概率。检查一下训练和推理过程中分别送入模型的数据,src端和tgt端是否都有EOS结尾。 如果CAAT在每个决策片段(一次search_at)都会循环,就是说模型输出blank(bos)分数过低,这种情况我没遇到过,可能模型训练有些异常,你可以把训练log发我看一下。另外可以调模型推理时的bos_bias参数到一个大于0的数(加大出bos的概率)来解码看一下。

dearchill commented 2 years ago

是只在过短的数据上有这种现象还是长的数据也会重复翻译?看上去有点像模型走到最后仍然不输出EOS符号导致循环解码,可以调试观察一下循环开始时的bos和eos输出概率。检查一下训练和推理过程中分别送入模型的数据,src端和tgt端是否都有EOS结尾。 如果CAAT在每个决策片段(一次search_at)都会循环,就是说模型输出blank(bos)分数过低,这种情况我没遇到过,可能模型训练有些异常,你可以把训练log发我看一下。另外可以调模型推理时的bos_bias参数到一个大于0的数(加大出bos的概率)来解码看一下。

看起来短句和长句都有这个问题,我再按照您的建议仔细研究一下~

danliu2 commented 2 years ago

调试看一下source没输入完时(is_end=False)search_at对这一块数据翻译能否正常输出eos出来,还是说只在最后停不下来出现循环。

dearchill commented 2 years ago

调试看一下source没输入完时(is_end=False)search_at对这一块数据翻译能否正常输出eos出来,还是说只在最后停不下来出现循环。

抱歉这么久回复,前几天被别的事耽搁了。我使用的是二进制处理好的数据,在训练时详细打印了tokens,src端和tgt端都有eos结尾,未发现不正常的样本(而且数据用于训练别的模型例如原生的waitk和mma模型均正常),排除是训练数据的原因; 然后推理阶段,CAAT的确在每次search_at都会循环,在第一次,也就是prev_tokens刚初始化为0的时候,输出就已经有大量重复,也就是最上面打印的结果,因此后面在已经重复的prev_tokens上继续推理,产生的结果也一直是重复的。 因此怀疑还是训练时的问题,训练的log部分如下:

2022-09-15 15:43:04 | INFO | train_inner | epoch 001: 100 / 6798 loss=nan, delay_loss=-inf, prob_loss=inf, nll_loss=16.076, ppl=69067.3, wps=78601.5, ups=1, wpb=78232.8, bsz=3092.2, num_updates=100, lr=1.25975e-05, gnorm=1.776, clip=41, train_wall=104, gb_free=67.3, wall=123 2022-09-15 15:44:42 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:44:42 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:44:42 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:44:42 | INFO | train_inner | epoch 001: 200 / 6798 loss=nan, delay_loss=nan, prob_loss=inf, nll_loss=14.24, ppl=19355.9, wps=79276.1, ups=1.01, wpb=78137.8, bsz=3145.1, num_updates=200, lr=2.5095e-05, gnorm=0.863, clip=0, train_wall=98, gb_free=67.2, wall=222 2022-09-15 15:46:21 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:46:21 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:46:21 | WARNING | root | NaN or Inf found in input tensor. 2022-09-15 15:46:21 | INFO | train_inner | epoch 001: 300 / 6798 loss=nan, delay_loss=nan, prob_loss=inf, nll_loss=12.472, ppl=5682.71, wps=79539.8, ups=1.01, wpb=78475.4, bsz=3125.4, num_updates=300, lr=3.75925e-05, gnorm=0.656, clip=0, train_wall=98, gb_free=67.3, wall=321

其中几个loss一直是nan或者inf,因此我在attention_transducer.py的390行附近,打印rnnt计算的loss,时不时就会有nan和inf以及-inf出现,而cross_entropy的loss都是正常的。请问rnnt这样的loss输出应该是不正常的吧,我是按照readme里面的说明编译安装的,会不会是环境的问题,我的cuda版本是11.4,pytorch版本是1.10.0

danliu2 commented 2 years ago

模型训练中不应该出现loss为nan或inf,现象有点奇怪,我此前实验中没有遇到过。猜测一些可能问题:1. 因某些原因导致caat 的输出T*N*V的分数分布畸形(比如blank标记输出概率一直接近0或对数概率-30以下),调试观察一下输出分数,重点是是bos的值。从没有出nan的那个checkpoint往后训,调整一下延迟惩罚等权重看一下;2.可能和fp16训练的scale有关,检查train_step是否将优化器的scaler正常传入或换为float32训练。3. 看一下比较早期的没有出nan的checkpoint解码是否正常 我当初做这块工作时pytorch版本1.4,fairseq也是比较早的版本,但估计目前的异常和框架版本应该没关系。

dearchill commented 2 years ago

模型训练中不应该出现loss为nan或inf,现象有点奇怪,我此前实验中没有遇到过。猜测一些可能问题:1. 因某些原因导致caat 的输出TNV的分数分布畸形(比如blank标记输出概率一直接近0或对数概率-30以下),调试观察一下输出分数,重点是是bos的值。从没有出nan的那个checkpoint往后训,调整一下延迟惩罚等权重看一下;2.可能和fp16训练的scale有关,检查train_step是否将优化器的scaler正常传入或换为float32训练。3. 看一下比较早期的没有出nan的checkpoint解码是否正常 我当初做这块工作时pytorch版本1.4,fairseq也是比较早的版本,但估计目前的异常和框架版本应该没关系。

更换了cuda10.2+pytorch1.6的镜像,目前训练看上去没有问题了。因为之前从第一个epoch开始rnnt的loss就有nan和inf出现,调整了参数也没用,而且我之前用fp32训练的,正常情况也不容易梯度爆炸,因此我怀疑还是rnnt编译的时候环境的问题,现在更换了环境重新编译,使用fp16也正常训练了,因为batch只能设很小,我再多训练一段时间看看情况。再次感谢您的帮助~

dearchill commented 2 years ago

Solved.