use the same gradient to maximize one part of the model and minimize another part of the same model
The trick you are looking for is called the Gradient Reversal Layer. It is a layer that does nothing (i.e., identity) in the forward pass, but it reverts the sign of the gradient, so everything behind the layer optimizes the opposite of the loss function.
There are several PyTorch implementations:

https://github.com/janfreyberg/pytorch-revgrad
https://github.com/jvanvugt/pytorch-domain-adaptation/blob/master/utils.py

Initially, it was introduced for unsupervised domain dataptaion. Now it has quite a lot of applications, such as removing sensitive information from CV representation or removing language identity from multilingual contextual embeddings.