longformer / tests /test_sliding_chunks.py
aliabd
full working demo
eedb413
Raw
History Blame Contribute Delete
3.43 kB
import time
import unittest
import torch
import numpy as np
import random
from longformer.diagonaled_mm_tvm import diagonaled_mm as diagonaled_mm_tvm, mask_invalid_locations
from longformer.sliding_chunks import sliding_chunks_matmul_pv, sliding_chunks_matmul_qk
def same_storage(x, y):
'''Tests if two tensors share the same underlying storage (for memory optimizations)'''
return x.storage().data_ptr() == y.storage().data_ptr()
class TestSlidingChunksMM(unittest.TestCase):
def test_tvm_equal_sliding_chunks(self):
np.random.seed(3)
random.seed(3)
torch.manual_seed(3)
torch.cuda.manual_seed(3)
torch.cuda.manual_seed_all(3)
torch.set_printoptions(sci_mode=False)
N = 4096 # * 16
M = 64 # hidden size
W = 256 # one sided. Actual window size = 2w+1
B = 3
D = 1 # no dilation
H = 12 # number of heads
autoregressive = False # not autoregressive
device = 'cuda'
dtype = torch.float32
failed_tests = 0
time1 = time2 = 0
for i in range(50):
if i < 5:
time1 = time2 = 0 # don't include the first few iterations because of high variance
query = torch.randn(B * N * H * M, requires_grad=True, device=device, dtype=dtype).view(B, N, H, M)
key = torch.randn(B * N * H * M, requires_grad=True, device=device, dtype=dtype).flip(dims=(0,)).view(B, N, H, M)
value = torch.randn(B * N * H * M, requires_grad=True, device=device, dtype=dtype).view(B, N, H, M)
# TVM MM
torch.cuda.synchronize()
start = time.time()
attention1 = diagonaled_mm_tvm(query, key, W, D, False, 0, autoregressive)
mask_invalid_locations(attention1, W, D, autoregressive)
attention_probs1 = torch.nn.functional.softmax(attention1, dim=-1)
context1 = diagonaled_mm_tvm(attention_probs1, value, W, D, True, 0, autoregressive)
context1.sum().backward()
torch.cuda.synchronize()
time1 += time.time() - start
torch.cuda.empty_cache()
# query = query.half() # uncomment to profile the fp16 performance
# key = key.half()
# value = value.half()
assert D == 1
assert not autoregressive
torch.cuda.synchronize()
start = time.time()
attention2 = sliding_chunks_matmul_qk(query, key, W, float('-inf'))
attention_probs2 = torch.nn.functional.softmax(attention2, dim=-1)
context2 = sliding_chunks_matmul_pv(attention_probs2, value, W)
context2.sum().backward()
torch.cuda.synchronize()
time2 += time.time() - start
torch.cuda.empty_cache()
try:
assert torch.allclose(attention1, attention2.float(), atol=1e-4, rtol=1e-5)
assert torch.allclose(context1, context2.float(), atol=1e-4, rtol=1e-5)
except AssertionError:
failed_tests += 1
print('Time tvm: {0:.5f} s'.format(time1))
print('Time pytorch sliding chunks: {0:.5f} s'.format(time2))
print('Sliding chunks vs. TVM speedup: {0:.5f}x'.format(time1/time2))
print(f'Failed tests: {failed_tests}/{i+1}')
assert failed_tests == 0
if __name__ == '__main__':
unittest.main()