code: def forward(
      self, z_e: Tensor, *, return_z_q_g: bool = False
  ) -> VQCodebookOut:
      inp = z_e
      z_e = z_e.permute(0, 2, 3, 1).contiguous()
  
      codebook = self.embedding.weight.detach()
      with torch.no_grad():
          z_e_flattened = z_e.view(-1, self.code_dimension)
          distances = (
              torch.sum(z_e_flattened**2, dim=1, keepdim=True)
              + torch.sum(codebook**2, dim=1)
              - 2.0
              * torch.einsum("bd,dn->bn", z_e_flattened, codebook.t())
          )
          indices = torch.argmin(distances, dim=1)
  
      z_q_flattened = codebook[indices]
      z_q = z_q_flattened.view_as(z_e)
      # VQSTE in one line of code
      z_q = z_e + (z_q - z_e).detach()
  
      indices = indices.view(*z_q.shape[:-1])
      z_q = z_q.permute(0, 3, 1, 2).contiguous()
  
      if not return_z_q_g:
          return VQCodebookOut(inp, z_q, indices)
  
      # z_q with embedding gradient
      z_q_g_flattened = self.embedding.weight[indices]
      z_q_g = z_q_g_flattened.view_as(inp)
      return VQCodebookOut(inp, z_q, indices, z_q_g)
  
imports: import torch
  from torch import nn
  from torch import Tensor
  from typing import Any
  from typing import Dict
  from typing import Optional
  from typing import NamedTuple
  from cftool.types import tensor_dict_type
  from .encoder import make_encoder
  from .encoder import IEncoder
  from .encoder import EncoderMixin
  from .decoder import make_decoder
  from .decoder import IDecoder
  from ...misc.toolkit import auto_num_layers
label_desc: Use image node_id 2 for calling the VQCodebook obj's underlying member method code with example usage: obj.forward(z_e) and returns: VQCodebookOut, VQCodebookOut