每周碎片知识30

[fairseq generate 编码问题]

fairseq在生成的时候:

1
CUDA_VISIBIE_DEVICES=2 python generate.py data-bin/wmt16_en_de_bpe32k/ --path checkpoints/wmt/checkpoint_best.pt --remove-bpe --beam 4 --batch-size 64 --lenpen 0.6 --max-len-a 1 --max-len-b 50 | tee generate.out

容易出现编码问题。

UnicodeEncodeError: ‘ascii’ codec can’t encode character ‘\xe4’ in position 42: ordinal not in range(128)

这个问题是python自身的编码问题。

解决方案是直接在代码里或系统配置里显式置为utf-8。
https://stackoverflow.com/questions/2276200/changing-default-encoding-of-python
如果只想临时设置,可以在命令行使用:

1
2
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

亲测有效。


[Pytorch梯度累积出现显存OOM问题]

关于梯度累积有两个版本:
①直接loss累加

1
2
3
4
5
6
for i in range(n):
loss=cal_loss(model, batch)
total_loss+=loss # accumulate loss
total_loss.backward()
optim.step()
model.zero_grad()

②每次计算backward,累积完gradient再更新

1
2
3
4
5
for i in range(n):
loss=cal_loss(model, batch)
loss.backward() # backward every time but no step
optim.step()
model.zero_grad()

其实二者的计算结果是一样的,但第一种方法的显存会显著大于第二种。因为直接loss的叠加,并没有将计算图释放掉,使得每次循环所生成的计算图保留(当backward计算完梯度后计算图才会释放),大大占用显存。而第二种方法每次只保留了梯度而将计算图释放,累积梯度n次所占的显存和不做梯度累积的显存是一样的。

https://discuss.pytorch.org/t/accumulating-gradients/30020