So I did some investigation
        # point 1
        output, _, _ = self.discriminator['model'](data)
        # point 2
        loss = self.discriminator['loss_fn'](output, target)
        # point 3
        loss.backward()
        # point 4
        self.discriminator['optimizer'].step()

At each point I printed requires_grad and grad
point 1 : data False None
point 1 : target False None
point 1 :  module.dis_model.0.weight True None
point 1 :  module.dis_model.0.bias True None
point 1 :  module.dis_model.2.weight True None
point 1 :  module.dis_model.2.bias True None
point 1 :  module.discriminator.0.weight True None
point 1 :  module.discriminator.0.bias True None
point 1 :  module.encoder.0.weight True None
point 1 :  module.encoder.0.bias True None
point 1 :  module.co_encoder.0.weight True None
point 1 :  module.co_encoder.0.bias True None

point 2 : output True None

point 3 : loss True None

point 4 : output True None
point 4 : target False None
point 4 : loss True None
point 4 : output True None
point 4 :  module.dis_model.0.weight True None
point 4 :  module.dis_model.0.bias True None
point 4 :  module.dis_model.2.weight True None
point 4 :  module.dis_model.2.bias True None
point 4 :  module.discriminator.0.weight True None
point 4 :  module.discriminator.0.bias True None
point 4 :  module.encoder.0.weight True None
point 4 :  module.encoder.0.bias True None
point 4 :  module.co_encoder.0.weight True None
point 4 :  module.co_encoder.0.bias True None

The network looks like this
  Discriminator(
  (dis_model): Sequential(
    (0): Linear(in_features=784, out_features=32, bias=True)
    (1): LeakyReLU(negative_slope=0.2)
    (2): Linear(in_features=32, out_features=32, bias=True)
    (3): LeakyReLU(negative_slope=0.2)
  )
  (discriminator): Sequential(
    (0): Linear(in_features=32, out_features=1, bias=True)
    (1): Sigmoid()
  )
  (encoder): Sequential(
    (0): Linear(in_features=32, out_features=5, bias=True)
    (1): Softmax()
  )
  (co_encoder): Sequential(
    (0): Linear(in_features=32, out_features=0, bias=True)
    (1): Softmax()
  )
)

In this training, I only care about output from discriminator, which goes through dis_model first
Should the requires_grad of input data be True? is that the issue?