code: def add_ops_without_layer_norm_op(self, net):
      # two issues here:
      #  1. use multiple ops to replace the function of LayerNorm
      #  2. do not use legacy broadcast
      ln_output = net.NextScopedBlob("ln_output")
      ln_mean = net.NextScopedBlob("ln_mean")
      ln_stdev = net.NextScopedBlob("ln_stdev")
      ln_mean_arr = net.NextScopedBlob("ln_mean_arr")
      net.ReduceBackMean(self.input_record.field_blobs(), [ln_mean_arr])
      net.ExpandDims([ln_mean_arr], [ln_mean], dims=[1])
      ln_centered = net.NextScopedBlob("ln_centered")
      net.Sub(
          self.input_record.field_blobs() + [ln_mean], [ln_centered]
      )
      ln_sqr = net.NextScopedBlob("ln_sqr")
      net.Sqr([ln_centered], [ln_sqr])
      ln_sqr_mean = net.NextScopedBlob("ln_sqr_mean")
      net.ReduceBackMean([ln_sqr], [ln_sqr_mean])
      ln_var = net.NextScopedBlob("ln_var")
      net.Add([ln_sqr_mean, self.epsilon], ln_var)
      ln_std_arr = net.NextScopedBlob("ln_std_arr")
      net.Pow([ln_var], [ln_std_arr], exponent=0.5)
      net.ExpandDims([ln_std_arr], [ln_stdev], dims=[1])
      net.Div([ln_centered, ln_stdev], [ln_output])
      ln_scaled = net.NextScopedBlob("ln_scaled")
      net.Mul([ln_output, self.scale], [ln_scaled])
      net.Add([ln_scaled, self.bias], self.output_schema.field_blobs())
  
file_path: pytorch/caffe2/python/layers/layer_normalization.py
imports: from caffe2.python import schema
  from caffe2.python.layers.layers import ModelLayer
  import numpy
label_desc: Use image node_id 3 for calling the LayerNormalization obj's underlying member method code with example usage: obj.add_ops_without_layer_norm_op(net) without return types