每周碎片知识27

[Pytorch加速建议]

9 Tips For Training Lightning-Fast Neural Networks In Pytorch

其中几条比较有意思。

Retained graphs

在保存loss的时候,要注意:

1
2
3
4
# bad
losses.append(loss)
# good
losses.append(loss.item())

因为前者会保存整张计算图,占用大量内存。

Moving to Multiple GPUs

一般我们都是Split-batch,也即:

实现Split-batch只需要使用Pytorch的DataParallel。

而另一个方法是Split Model Training,也即:

比如说翻译模型有encoder与decoder部分,那么可以将encode/decoder放在不同GPU。

1
2
3
4
5
6
7
8
9
10
11
12
13

# each model is sooo big we can't fit both in memory
encoder_rnn.cuda(0)
decoder_rnn.cuda(1)

# run input through encoder on GPU 0
encoder_out = encoder_rnn(x.cuda(0))

# run output through decoder on the next GPU
out = decoder_rnn(encoder_out.cuda(1))

# normally we want to bring all outputs back to GPU 0
out = out.cuda(0)

当然也可以将二者结合起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# change these lines
self.encoder = RNN(...)
self.decoder = RNN(...)

# to these
# now each RNN is based on a different gpu set
self.encoder = DataParallel(self.encoder, devices=[0, 1, 2, 3])
self.decoder = DataParallel(self.encoder, devices=[4, 5, 6, 7])

# in forward...
out = self.encoder(x.cuda(0))

# notice inputs on first gpu in device
sout = self.decoder(out.cuda(4)) # <--- the 4 here

Faster multi-GPU training on a single node

在单个机器也使用DistributedDataParallel,DistributedDataParallel会比DataParallel更快,DistributedDataParallel只需要gradient的同步。


[Python assert]

Python 使用断言的最佳时机

对一个函数而言,一般情况下,断言用于检查函数输入的合法性,要求输入满足一定的条件才能继续执行;

assert时候的几个情况:
防御性的编程:为了防范由于以后的代码变更而发生错误
运行时对程序逻辑的检测
合约性检查(比如前置条件,后置条件)
程序中的常量
检查文档


[Python global关键字]

对于什么时候必须要使用global关键字。如果函数内部只使用变量而不修改/赋值,则不需要显式在函数内部global;否则就必须要global。因为内部做了改变(赋值),编译器会认为该变量是函数内部的local变量而不是外部的全局变量。

如:

1
2
3
4
5
6
7
model = Classifier(args)
optimizer=torch.optim.SGD(model.parameters())
...
def main():
global model # 必须显式加global,因为在main内部做了改变
model.train()
train(model,optimizer) # optimizer由于没有在main函数内部改变,因此不需要global