+ import argparse
+
+ import numpy as np
+ import matplotlib.pyplot as plt
+ import matplotlib.collections as mc
+
+ args = argparse.Namespace(
+ gate_dropout_proba=0.0, gate_dropout_sync=True, gate_dropout_replace=False
+ )
+
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
+
+ dim_model, dim_keys, nb_heads = 512, 64, 1
+ dropout = 0.1
+
+ caterpillar = Caterpillar(
+ dim_model=dim_model,
+ dim_qk=dim_keys,
+ dim_v=dim_model // nb_heads,
+ nb_heads=nb_heads,
+ caterpillar_length=16,
+ caterpillar_height=32,
+ attention_dropout=dropout,
+ args=args,
+ ).to(device)
+
+ qkv = QKVAttention(
+ dim_model=dim_model,
+ dim_qk=dim_keys,
+ dim_v=dim_model // nb_heads,
+ nb_heads=nb_heads,
+ causal=True,
+ attention_dropout=dropout,
+ args=args,
+ ).to(device)
+
+ linear = CacheWrapper(nn.Linear(512, 512)).to(device)
+
+ x = torch.randn(1, 256, dim_model)
+
+ x = x.to(device)
+ x.requires_grad_()
+
+ ######################################################################
+
+ fig = plt.figure()
+ fig.set_figheight(6)
+ fig.set_figwidth(8)
+
+ ax = fig.add_subplot(1, 1, 1)
+
+ # ax.set_xlim(-1.5, 1.5)
+ # ax.set_ylim(-1.5, 1.5)
+ # ax.set(aspect=1)
+ # ax.spines.right.set_visible(False)
+ # ax.spines.top.set_visible(False)
+
+ # dt = 0.01
+ # t = np.arange(dt, 20.0, dt)
+ # ax.semilogx(t, np.exp(-t / 5.0))
+ # ax.grid()
+ ax.set_yscale("log")
+
+ ######################################################################
+
+ for label, model, thickness in [
+ ("nn.Linear", linear, 0.2),
+ ("mygpy.QKVAttention", qkv, 1),
+ ("mygpt.Caterpillar", caterpillar, 2),
+ ]:
+ y = model(BracketedSequence(x, 32, x.size(1) - 32, init_cache=True)).x
+
+ for n, p in [("input", x)] + list(model.named_parameters()):
+ print(f"Processing {model}.{n}")
+ data = []
+ for t in range(y.size(1)):
+ sg = 0
+ for d in torch.randperm(y.size(2))[:8]:
+ sg += torch.autograd.grad(y[0, t, d], p, retain_graph=True)[0]
+ assert not sg.isinf().any()
+ assert not sg.isnan().any()
+ data.append([t, sg.sum().item()])
+
+ data = torch.tensor(data)
+ # cx, cy = data[:, 0], data[:, 1]
+ cy = data[:, 1].sort().values
+ cx = torch.linspace(0, 1, cy.size(0))
+ ax.plot(
+ cx, cy, label=label + "." + n, linewidth=thickness
+ ) # , color='gray', label='Input')
+
+ # ax.legend(frameon=False, loc="top right")
+
+ # Put a legend to the right of the current axis
+ box = ax.get_position()
+ ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
+ ax.legend(loc="center left", bbox_to_anchor=(1, 0.5))
+
+ filename = "plot.pdf"
+ print(f"saving {filename}")
+ fig.savefig(filename, bbox_inches="tight")
+
+ # if args.window and hasattr(plt.get_current_fig_manager(), 'window'):
+ # plt.get_current_fig_manager().window.setGeometry(2, 2, 1024, 768)
+ # plt.show()
+
+ exit(0)
+
+ ######################################################################