Thank you @ptrblck,
I modified the code for my use case but the alpha variable in the following code not have a gradient, what am I missing?
import torch
import torch.nn as nn
import torch.nn.functional  as F

# Setup
lin = nn.Linear(5, 5, bias=False)
alpha = nn.Parameter(torch.randn(5, 2))
eign_vect = torch.rand(2, 5)
weight = nn.Parameter(torch.matmul(alpha, eign_vect))
optimizer = torch.optim.SGD([weight, alpha], lr=1.)

# Freeze lin.weight
lin.weight.requires_grad = False

# Forward pass
x = torch.randn(1, 5)
out = F.linear(x, lin.weight + weight)
# Backward pass
out.mean().backward()

# Check grads
print(lin.weight.grad)
# > None
print(alpha.grad)
# > None
print(weight.grad)
# > tensor([[-0.0892, -0.3502, -0.0987, -0.3553, -0.2443],
#           [-0.0892, -0.3502, -0.0987, -0.3553, -0.2443],
#           [-0.0892, -0.3502, -0.0987, -0.3553, -0.2443],
#           [-0.0892, -0.3502, -0.0987, -0.3553, -0.2443],
#           [-0.0892, -0.3502, -0.0987, -0.3553, -0.2443]])

# Step
optimizer.step()

And I only want to update the alpha variable (not weight), How I can do it?