code: def _get_output_act_obs_or_fq(
      arg: Node,
      named_modules: Dict[str, torch.nn.Module],
      obs_or_fq_map: Dict[EdgeOrNode, ObserverOrFakeQuantize],
      is_qat: bool,
  ) -> ObserverOrFakeQuantize:
      """Get the constructor for observer or fake quant object for
      the argument in the original graph as the output of previous node,
      skipping inserted observers
  
      We are assuming that the observers are inserted correctly, and the dtype for
      argument in quantized graph will match what is specified by the qconfig
      """
      assert isinstance(arg, Node)
      if "quantization_annotation" in arg.meta:
          return _create_obs_or_fq_from_qspec(
              arg.meta["quantization_annotation"].output_qspec,
              obs_or_fq_map,
              is_qat,
          )
  
      # Custom module LSTM output is a tuple that we broke down into the internal nodes in order
      # to insert DeQuantStubs (see `_insert_dequant_stubs_for_custom_module_lstm_output`).
      # Since we modified the graph in this case, we must trace back from the args through
      # the specific nodes we added in order to reach the original LSTM node. Otherwise, we would
      # not be able to accurately detect whether this node is a consumer of custom module LSTM.
      custom_module_lstm_node = (
          _maybe_get_custom_module_lstm_from_node_arg(
              arg, named_modules
          )
      )
      output_act_obs_or_fq_ctr = None
      if custom_module_lstm_node is not None:
          output_act_obs_or_fq_ctr = custom_module_lstm_node.meta[
              "target_dtype_info"
          ]["output_act_obs_or_fq_ctr"]
          output_act_obs_or_fq = (
              output_act_obs_or_fq_ctr()
              if output_act_obs_or_fq_ctr
              else None
          )
      elif _is_activation_post_process_node(arg, named_modules):
          observed_arg = arg.args[0]
          assert isinstance(
              observed_arg, Node
          ), "Currently we only support observing Node"
          if "quantization_annotation" in observed_arg.meta:
              output_act_obs_or_fq = _create_obs_or_fq_from_qspec(
                  observed_arg.meta[
                      "quantization_annotation"
                  ].output_qspec,
                  obs_or_fq_map,
                  is_qat,
              )
          else:
              assert "target_dtype_info" in observed_arg.meta
              output_act_obs_or_fq_ctr = observed_arg.meta[
                  "target_dtype_info"
              ]["output_act_obs_or_fq_ctr"]
              output_act_obs_or_fq = (
                  output_act_obs_or_fq_ctr()
                  if output_act_obs_or_fq_ctr
                  else None
              )
      else:
          if "target_dtype_info" in arg.meta:
              output_act_obs_or_fq_ctr = arg.meta[
                  "target_dtype_info"
              ].get(
                  "output_act_obs_or_fq_ctr",
                  _DEFAULT_FP32_OBS_OR_FQ_CTR,
              )
          else:
              output_act_obs_or_fq_ctr = _DEFAULT_FP32_OBS_OR_FQ_CTR
          output_act_obs_or_fq = (
              output_act_obs_or_fq_ctr()
              if output_act_obs_or_fq_ctr
              else None
          )
  
      return output_act_obs_or_fq
  
imports: import copy
  import torch
  import warnings
  from torch.fx import GraphModule
  from torch.fx.graph import Graph, Node
  from torch.fx.node import Argument
  from ..quantize import propagate_qconfig_
  from ..observer import _is_activation_post_process, _PartialWrapper
  from ..qconfig import _is_reuse_input_qconfig, QConfigAny
  from ..qconfig_mapping import QConfigMapping
  from .qconfig_mapping_utils import _generate_node_name_to_qconfig, _update_qconfig_for_fusion, _get_flattened_qconfig_dict, _update_qconfig_for_qat
  from .quantize_handler import _default_root_node_getter, _get_pattern_to_quantize_handlers, QuantizeHandler
  from torch.ao.quantization import ObserverBase, FixedQParamsObserver, FixedQParamsFakeQuantize, _DerivedObserverOrFakeQuantize
  from torch.ao.quantization.utils import Pattern, NodePattern
  from ._equalize import is_equalization_observer, node_supports_equalization
  from .pattern_utils import _sorted_patterns_dict
  from .match_utils import _MatchResultWithQConfig, _find_matches
  from .utils import _insert_dequant_stubs_for_custom_module_lstm_output, _is_custom_module_lstm, _maybe_get_custom_module_lstm_from_node_arg, _qconfig_satisfies_dtype_config_constraints, get_custom_module_class_keys, all_node_args_have_no_tensors, assert_and_get_unique_device, get_non_observable_arg_indexes_and_types, get_new_attr_name_with_prefix, node_arg_is_weight, node_arg_is_bias, NON_QUANTIZABLE_WEIGHT_OPS, ObservedGraphModuleAttrs
  from torch.ao.quantization import PlaceholderObserver
  from torch.ao.quantization.quantize import convert
  from ..utils import _parent_name, get_qconfig_dtypes, get_swapped_custom_module_class
  from ..backend_config.utils import get_pattern_to_dtype_configs, get_module_to_qat_module, get_fusion_pattern_to_root_node_getter
  from ..backend_config import BackendConfig, DTypeConfig, get_native_backend_config
  from .custom_config import PrepareCustomConfig, StandaloneModuleConfigEntry
  from torch.ao.quantization.quantizer import EdgeOrNode, QuantizationSpec, QuantizationSpecBase, FixedQParamsQuantizationSpec, SharedQuantizationSpec, DerivedQuantizationSpec
  from torch.ao.quantization import ObserverOrFakeQuantize
  from torch._subclasses import FakeTensor
  from typing import Any, Dict, List, Optional, Set, Tuple, Type, Union
  from dataclasses import asdict
label_desc: Use image node_id 17 for calling a global function with example usage: _get_output_act_obs_or_fq(arg, named_modules, obs_or_fq_map, is_qat) and returns: output_act_obs_or_fq, _create_obs_or_fq_from_qspec