nn.Embedding has the option for a padding_idx (check docs).
padding_idx controls the padding index. When you send in q1 or q2 containing this index, zeros are returned and they are ignored for gradient.
So you can send q1 and q2 to be mini-batches padded to the maximum length of your sequence, and padded with the value padding_idx.
after getting q1_embeds and q2_embeds and before the mean operation, you might have to do a torch.gather of specific indices before doing mean, or do the mean operation in a for loop.