class_docstr: Transformation that merges linear layers that take the same input into one big linear layer.
class_docstr_tok: ["Transformation","that","merges","linear","layers","that","take","the","same","input","into","one","big","linear","layer","."]
code: def _unmerge_linears(
      graph_module: "GraphModule",
      merged_linear_node: "Node",
      merged_linear: torch.nn.Linear,
  ):
      # The linear node targets and the output nodes need to be in the same order.
      # merge_linear_name gives the order in which the weights were concatenated, and we use the slice start index to
      # sort the output nodes since the start index tells when a weight was concatenated.
      linear_node_targets = merged_linear_node.linear_node_targets
      output_nodes = sorted(
          merged_linear_node.users,
          key=lambda node: node.args[1][1].start,
      )
  
      in_features = merged_linear.in_features
      out_features = []
      for node in output_nodes:
          slice_to_get = node.args[1][1]
          out_features.append(slice_to_get.stop - slice_to_get.start)
  
      linears = [
          torch.nn.Linear(
              in_features,
              out_feat,
              bias=hasattr(merged_linear, "bias"),
              device=merged_linear.weight.device,
              dtype=merged_linear.weight.dtype,
          )
          for out_feat in out_features
      ]
  
      # fully_qualified_parent_name = merged_linear_node.target.rsplit(".", maxsplit=1)[0]
      # parent_module = graph_module.get_submodule(fully_qualified_parent_name)
      # parent_module_name = merged_linear_node.target.rsplit(".", maxsplit=1)[0]
      for target, node, linear in zip(
          linear_node_targets, output_nodes, linears
      ):
          with torch.no_grad():
              slice_to_get = node.args[1][1]
              linear.weight = torch.nn.Parameter(
                  merged_linear.weight[
                      slice_to_get.start : slice_to_get.stop
                  ]
              )
              if hasattr(merged_linear, "bias"):
                  linear.bias = torch.nn.Parameter(
                      merged_linear.bias[
                          slice_to_get.start : slice_to_get.stop
                      ]
                  )
          (
              parent_module,
              name,
          ) = MergeLinears._linear_node_to_module_and_attribute_name(
              graph_module, target
          )
          parent_module.add_module(name, linear)
          node.op = "call_module"
          node.target = target
          node.args = (merged_linear_node.args[0],)
  
      (
          parent_module,
          merged_linear_name,
      ) = MergeLinears._linear_node_to_module_and_attribute_name(
          graph_module, merged_linear_node.target
      )
      delattr(parent_module, merged_linear_name)
      graph_module.graph.erase_node(merged_linear_node)
  
imports: import collections
  import copy
  import functools
  import itertools
  import operator
  import warnings
  from abc import ABC, abstractmethod
  from typing import TYPE_CHECKING, List
  import torch
  from transformers.file_utils import add_end_docstrings
  from transformers.utils.fx import _gen_constructor_wrapper
label_desc: Use image node_id 5 for calling the MergeLinears obj's underlying member method code with example usage: obj._unmerge_linears(graph_module, merged_linear_node, merged_linear) without return types