I’m not sure what simulatenous training means here as it seems like the overall model is still feedforward.
You can likely port most of this implementation over by simply pattern matching (e.g., tf.keras.layers.Layer → torch.nn.Module, def call(self, inputs) → def forward(self, x)).
torchvision has many good reference model implementations that are good examples of this (e.g., ResNet: torchvision.models.resnet — Torchvision master documentation 1).