You are using one big model anyway at least memory-wise. And you can always access inner model directly by calling model.basemodel(x)
as for your question, it should work fine:
import torch
import torch.nn as nn


class Model1(nn.Module):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(10, 100)

    def forward(self, x):
        return self.l1(x)


class Model2(nn.Module):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(100, 1)

    def forward(self, x):
        return self.l1(x)


m1 = Model1()
m2 = Model2()

opt1 = torch.optim.SGD(m1.parameters(), lr=1e-3)
opt2 = torch.optim.SGD(m2.parameters(), lr=1e-3)

loss_fn = nn.MSELoss()

batchsize = 32
x = torch.ones((batchsize, 10)).float()
labels = torch.ones((batchsize, 10)).float()

for epoch in range(50):

    opt1.zero_grad()
    opt2.zero_grad()
    y = m1(x)
    z = m2(y)
    loss = loss_fn(z, labels)
    print(f'Epoch: {epoch}, loss: {loss.item():.4f}')
    loss.backward()
    opt1.step()
    opt2.step()