You should move the initialization of submodules out into __init__ rather than in your model’s forward. This will also likely improve performance since costly parameter allocations only need to happen once instead of on each run of your model’s forward.
class M(nn.Module):
    def __init__(self, num_nodes, num_feats):
        self.features = nn.Embedding(num_nodes, num_feats)
        self.features.weight = nn.Parameter(torch.FloatTensor(feat_data), requires_grad=False)
    
    def forward(self, nodes):
        result = self.features(...)
        ...

model = M()
script_model = torch.jit.script(model)
script_model.save("script_model.pt")

When classes are instantiated in TorchScript, the entire class must be compatible with the TorchScript compiler (details 32), which is not the case for most nn.Modules. However, if nn.Modules are saved on self in __init__, only the methods that are actually used in the forward of your model M need to be compatible with the compiler (which should work for any module in nn except for these 3 30).