parameters: (self, reshape_q: NodeProto)
return_statement: return num_heads, hidden_size
docstring: Detect num_heads and hidden_size from a reshape node.
  
          Args:
              reshape_q (NodeProto): reshape node for Q
  
          Returns:
              Tuple[int, int]: num_heads and hidden_size
docstring_summary: Detect num_heads and hidden_size from a reshape node.
docstring_tokens: Detect num_heads and hidden_size from a reshape node .
function: def get_num_heads_and_hidden_size(self, reshape_q: NodeProto) -> Tuple[int, int]:
          """ Detect num_heads and hidden_size from a reshape node.
  
          Args:
              reshape_q (NodeProto): reshape node for Q
  
          Returns:
              Tuple[int, int]: num_heads and hidden_size
          """
  
          # we assume that reshape fusion has done, so the shape is a tensor like [0, 0, num_heads, head_size]
          q_shape = self.model.get_initializer(reshape_q.input[1])
          if q_shape is None:
              logger.debug(f"{reshape_q.input[1]} is not initializer.")
              return self.num_heads, self.hidden_size  # Fall back to user specified value
  
          q_shape_value = NumpyHelper.to_array(q_shape)
          if len(q_shape_value) != 4 or (q_shape_value[2] <= 0 or q_shape_value[3] <= 0):
              logger.debug(f"q_shape_value={q_shape_value}. Expected value are like [0, 0, num_heads, head_size].")
              return self.num_heads, self.hidden_size  # Fall back to user specified value
  
          num_heads = q_shape_value[2]
          head_size = q_shape_value[3]
          hidden_size = num_heads * head_size
  
          if self.num_heads > 0 and num_heads != self.num_heads:
              if self.num_heads_warning:
                  logger.warning(f"--num_heads is {self.num_heads}. Detected value is {num_heads}. Using detected value.")
                  self.num_heads_warning = False  # Do not show the warning more than once
  
          if self.hidden_size > 0 and hidden_size != self.hidden_size:
              if self.hidden_size_warning:
                  logger.warning(
                      f"--hidden_size is {self.hidden_size}. Detected value is {hidden_size}. Using detected value.")
                  self.hidden_size_warning = False  # Do not show the warning more than once
  
          return num_heads, hidden_size
function_tokens: def get_num_heads_and_hidden_size ( self , reshape_q : NodeProto ) -> Tuple [ int , int ] : # we assume that reshape fusion has done, so the shape is a tensor like [0, 0, num_heads, head_size] q_shape = self . model . get_initializer ( reshape_q . input [ 1 ] ) if q_shape is None : logger . debug ( f"{reshape_q.input[1]} is not initializer." ) return self . num_heads , self . hidden_size # Fall back to user specified value q_shape_value = NumpyHelper . to_array ( q_shape ) if len ( q_shape_value ) != 4 or ( q_shape_value [ 2 ] <= 0 or q_shape_value [ 3 ] <= 0 ) : logger . debug ( f"q_shape_value={q_shape_value}. Expected value are like [0, 0, num_heads, head_size]." ) return self . num_heads , self . hidden_size # Fall back to user specified value num_heads = q_shape_value [ 2 ] head_size = q_shape_value [ 3 ] hidden_size = num_heads * head_size if self . num_heads > 0 and num_heads != self . num_heads : if self . num_heads_warning : logger . warning ( f"--num_heads is {self.num_heads}. Detected value is {num_heads}. Using detected value." ) self . num_heads_warning = False # Do not show the warning more than once if self . hidden_size > 0 and hidden_size != self . hidden_size : if self . hidden_size_warning : logger . warning ( f"--hidden_size is {self.hidden_size}. Detected value is {hidden_size}. Using detected value." ) self . hidden_size_warning = False # Do not show the warning more than once return num_heads , hidden_size