Einops 26 recently got support for various repeat-like patterns. Examples:
>>> x
tensor([[0, 1],
        [2, 3]])

Tile over the first axis:
>>> from einops import repeat
>>> repeat(x, 'i j -> (tile i) j', tile=2)
tensor([[0, 1],
        [2, 3],
        [0, 1],
        [2, 3]])

Tile over the second axis:
>>> repeat(x, 'i j -> i (tile j)', tile=2)
tensor([[0, 1, 0, 1],
        [2, 3, 2, 3]])

Tiling over both axes:
repeat(x, 'i j -> (tilei i) (tilej j)', tilei=2, tilej=3)