【问题标题】:PyTorch RNN is more efficient with `batch_first=False`?PyTorch RNN 使用 `batch_first=False` 更有效?
【发布时间】:2020-12-28 12:09:43
【问题描述】:

在机器翻译中,我们总是需要在注释和预测中切出第一个时间步(SOS 令牌)。

当使用batch_first=False 时,切掉第一个时间步仍然保持张量连续。

import torch
batch_size = 128
seq_len = 12
embedding = 50

# Making a dummy output that is `batch_first=False`
batch_not_first = torch.randn((seq_len,batch_size,embedding))
batch_not_first = batch_first[1:].view(-1, embedding) # slicing out the first time step

但是,如果我们使用batch_first=True,切片后,张量不再是连续的。我们需要使其连续,然后才能进行不同的操作,例如view

batch_first = torch.randn((batch_size,seq_len,embedding))
batch_first[:,1:].view(-1, embedding) # slicing out the first time step

output>>>
"""
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-8-a9bd590a1679> in <module>
----> 1 batch_first[:,1:].view(-1, embedding) # slicing out the first time step

RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
"""

这是否意味着batch_first=False 至少在机器翻译方面更好?因为它使我们免于执行contiguous() 步骤。有没有比batch_first=True 效果更好的情况?

【问题讨论】:

    标签: python nlp pytorch


    【解决方案1】:

    性能

    batch_first=Truebatch_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 作为0th 维度的 PyTorch 层时更简单(几乎所有 torch.nn 层都是这种情况,例如 torch.nn.Linear)。

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

    机器翻译

    应该更好,因为tensor 始终是连续的,并且不需要复制数据。使用[1:] 而不是[:,1:] 进行切片看起来也更干净。

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2018-12-24
      • 1970-01-01
      相关资源
      最近更新 更多