Python PyTorch RNN使用“批处理\u first=False”更有效?

Python PyTorch RNN使用“批处理\u first=False”更有效?,python,nlp,pytorch,Python,Nlp,Pytorch,在机器翻译中,我们总是需要切掉注释和预测中的第一个时间步(SOS标记) 使用batch\u first=False时,切掉第一个时间步仍然保持张量连续 导入火炬 批量大小=128 序号=12 嵌入=50 #生成一个“batch_first”的伪输出=False` 批次非第一批=torch.randn(顺序、批次大小、嵌入)) batch_not_first=batch_first[1:]视图(-1,嵌入)#切掉第一个时间步骤 但是,如果我们使用batch_first=True,在切片之后,张量

在机器翻译中,我们总是需要切掉注释和预测中的第一个时间步(SOS标记)

使用
batch\u first=False
时,切掉第一个时间步仍然保持张量连续

导入火炬
批量大小=128
序号=12
嵌入=50
#生成一个“batch_first”的伪输出=False`
批次非第一批=torch.randn(顺序、批次大小、嵌入))
batch_not_first=batch_first[1:]视图(-1,嵌入)#切掉第一个时间步骤
但是,如果我们使用
batch_first=True
,在切片之后,张量不再是连续的。我们需要先使其连续,然后才能执行不同的操作,例如
view

batch_first=torch.randn((批次大小、顺序、嵌入))
批处理_first[:,1::]视图(-1,嵌入)#切掉第一个时间步骤
输出>>>
"""
---------------------------------------------------------------------------
运行时错误回溯(上次最近调用)
在里面
---->1批处理_first[:,1::]视图(-1,嵌入)#切掉第一个时间步骤
RuntimeError:视图大小与输入张量的大小和跨距不兼容(至少有一个维度跨越两个相邻的子空间)。请改用.Reformate(…)。
"""
这是否意味着至少在机器翻译的背景下,
batch_first=False
更好?因为它避免了我们执行
continuous()
步骤。是否存在
batch\u first=True
效果更好的情况?

性能
batch\u first=True
batch\u first=False
之间似乎没有太大区别。请参阅下面的脚本:

import time

import torch


def time_measure(batch_first: bool):
    torch.cuda.synchronize()
    layer = torch.nn.RNN(10, 20, batch_first=batch_first).cuda()
    if batch_first:
        inputs = torch.randn(100000, 7, 10).cuda()
    else:
        inputs = torch.randn(7, 100000, 10).cuda()

    start = time.perf_counter()

    for chunk in torch.chunk(inputs, 100000 // 64, dim=0 if batch_first else 1):
        _, last = layer(chunk)

    return time.perf_counter() - start


print(f"Time taken for batch_first=False: {time_measure(False)}")
print(f"Time taken for batch_first=True: {time_measure(True)}")
在我的设备(GTX 1050 Ti)、PyTorch
1.6.0
和CUDA 11.0上,以下是结果:

Time taken for batch_first=False: 0.3275816479999776
Time taken for batch_first=True: 0.3159054920001836
(这两种情况各不相同,因此没有任何结论)

代码可读性
batch_first=True
当您想要使用需要
batch
作为
0
th维度的其他PyTorch层时(这是几乎所有
torch.nn
层的情况,例如)

在这种情况下,如果指定了
batch_first=False
,则必须
permute
返回张量

机器翻译 它应该更好,因为
张量
始终是连续的,不需要复制数据。使用
[1://code>而不是
[:,1://code>进行切片看起来也更干净