code: def transformer_decoder_attention_unit(
      x,
      hparams,
      encoder_output,
      decoder_self_attention_bias,
      encoder_decoder_attention_bias,
      attention_dropout_broadcast_dims,
      save_weights_to=None,
      make_image_summary=True,
  ):
      """Applies multihead attention function which is parametrised for decoding.
  
      Args:
        x: input (decoder input)
        hparams: model hyper-parameters
        encoder_output: Encoder representation. [batch_size, input_length,
          hidden_dim]
        decoder_self_attention_bias: Bias and mask weights for decoder
          self-attention. [batch_size, decoder_length]
        encoder_decoder_attention_bias: Bias and mask weights for encoder-decoder
          attention. [batch_size, input_length]
        attention_dropout_broadcast_dims: Fpr noise broadcasting in the dropout
          layers to save memory during training
        save_weights_to: an optional dictionary to capture attention weights for
          visualization; the weights tensor will be appended there under a string
          key created from the variable scope (including name).
        make_image_summary: Whether to make an attention image summary.
  
      Returns:
        The output tensor
      """
  
      with tf.variable_scope("self_attention"):
          y = common_attention.multihead_attention(
              common_layers.layer_preprocess(x, hparams),
              None,
              decoder_self_attention_bias,
              hparams.attention_key_channels or hparams.hidden_size,
              hparams.attention_value_channels or hparams.hidden_size,
              hparams.hidden_size,
              hparams.num_heads,
              hparams.attention_dropout,
              attention_type=hparams.self_attention_type,
              save_weights_to=save_weights_to,
              max_relative_position=hparams.max_relative_position,
              cache=None,
              make_image_summary=make_image_summary,
              dropout_broadcast_dims=attention_dropout_broadcast_dims,
              hard_attention_k=hparams.hard_attention_k,
          )
          x = common_layers.layer_postprocess(x, y, hparams)
      if encoder_output is not None:
          with tf.variable_scope("encdec_attention"):
              y = common_attention.multihead_attention(
                  common_layers.layer_preprocess(x, hparams),
                  encoder_output,
                  encoder_decoder_attention_bias,
                  hparams.attention_key_channels or hparams.hidden_size,
                  hparams.attention_value_channels
                  or hparams.hidden_size,
                  hparams.hidden_size,
                  hparams.num_heads,
                  hparams.attention_dropout,
                  save_weights_to=save_weights_to,
                  make_image_summary=make_image_summary,
                  dropout_broadcast_dims=attention_dropout_broadcast_dims,
                  hard_attention_k=hparams.hard_attention_k,
              )
              x = common_layers.layer_postprocess(x, y, hparams)
      return x
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import copy
  import functools
  from six.moves import range
  from tensor2tensor.layers import common_attention
  from tensor2tensor.layers import common_layers
  from tensor2tensor.models import transformer
  from tensor2tensor.utils import contrib
  from tensor2tensor.utils import expert_utils
  import tensorflow.compat.v1
label_desc: Use image node_id 8 for calling a global function with example usage: transformer_decoder_attention_unit(x, hparams, encoder_output, decoder__attention_bias, encoder_decoder_attention_bias, attention_dropout_broadcast_dims, save_weights_to, make_image_summary) and returns: x