def _try_apply_transform(
        reduce_op: Operation,
        block: Block,
        gamma_var: Var,
        beta_var: Var,
        epsilon_var: Var,
        end_op: Operation,
        ops_to_remove: List[Operation],
    ) -> bool:
        """
        Insert instance_norm / layer_norm and delete all ops.

        :param reduce_op: Start operation of the pattern.
        :param block: Block
        :param gamma_var: Gamma variable.
        :param beta_var: Beta variable.
        :param epsilon_var: Epsilon variable.
        :param end_op: End operation of the pattern.
        :param ops_to_remove: Operations to remove.
        """
        if not _check_no_output_connection(block, ops_to_remove):
            return False

        axes = reduce_op.axes.val
        rank = len(reduce_op.x.shape)

        # check whether the pattern is instance_norm or layer_norm
        is_layernorm = False
        is_instancenorm = False
        is_require_rank4_transpose = False

        negative_axes = [a - rank if a >= 0 else a for a in axes]
        negative_axes.sort()

        gamma_rank = gamma_var.rank if gamma_var is not None else -1
        beta_rank = beta_var.rank if beta_var is not None else -1

        if gamma_rank == len(axes) and beta_rank == len(axes):
            # axes for layer_norm must be [-1] or [-1, -2] or [-1, -2, -3] and so on
            if negative_axes == list(range(-len(negative_axes), 0)):
                is_layernorm = True

        if rank == 4 and negative_axes == [-3]:
            is_layernorm = (gamma_var is None and beta_var is None) or (gamma_rank == 1 and beta_rank == 1)

            if gamma_var:
                ops_to_remove.append(gamma_var.op)
                gamma_var = gamma_var.val
            else:
                gamma_var = None

            if beta_var:
                ops_to_remove.append(beta_var.op)
                beta_var = beta_var.val
            else:
                beta_var = None

        if rank == 4 and (negative_axes == [-2, -1] or negative_axes == [-3, -2]):
            if (
                len(np.squeeze(gamma_var.val).shape) == 1
                and len(np.squeeze(beta_var.val).shape) == 1
            ):
                is_instancenorm = True
            if negative_axes == [-3, -2]:
                is_require_rank4_transpose = True

        if not (is_instancenorm or is_layernorm):
            return False

        # remove all the ops, and replace with a layer_norm or instance_norm op
        out_name = end_op.outputs[0].name

        if is_require_rank4_transpose:
            x = mb.transpose(
                x=reduce_op.x,
                perm=[0, 3, 1, 2],
                name=out_name + "_transpose_nhwc_nchw",
                before_op=end_op,
            )
        if is_instancenorm:
            x = mb.instance_norm(
                x=x if is_require_rank4_transpose else reduce_op.x,
                gamma=np.squeeze(gamma_var.val),
                beta=np.squeeze(beta_var.val),
                epsilon=epsilon_var,
                name=out_name + "_instancenorm" if is_require_rank4_transpose else out_name,
                before_op=end_op,
            )
            ops_to_remove.extend([gamma_var.op, beta_var.op])
        else:  # is_layernorm
            x = mb.layer_norm(
                x=x if is_require_rank4_transpose else reduce_op.x,
                axes=axes,
                gamma=gamma_var,
                beta=beta_var,
                epsilon=epsilon_var,
                name=out_name + "_layernorm" if is_require_rank4_transpose else out_name,
                before_op=end_op,
            )
        if is_require_rank4_transpose:
            x = mb.transpose(
                x=x,
                perm=[0, 2, 3, 1],
                name=out_name + "_transpose_nchw_nhwc",
                before_op=end_op,
            )

        end_op.enclosing_block.replace_uses_of_var_after_op(
            anchor_op=end_op, old_var=end_op.outputs[0], new_var=x
        )
        # Remove all the ops at once
        block.remove_ops(ops_to_remove)
        return True

        Insert instance_norm / layer_norm and delete all ops.

        :param reduce_op: Start operation of the pattern.
        :param block: Block
        :param gamma_var: Gamma variable.
        :param beta_var: Beta variable.
        :param epsilon_var: Epsilon variable.
        :param end_op: End operation of the pattern.
        :param ops_to_remove: Operations to remove.
        
coremltools/converters/mil/mil/passes/defs/optimize_normalization.py