code: def get_feature_importances_from_botorch_model(
      model: Union[Model, ModuleList, None],
  ) -> np.ndarray:
      """Get feature importances from a list of BoTorch models.
  
      Args:
          models: BoTorch model to get feature importances from.
  
      Returns:
          The feature importances as a numpy array where each row sums to 1.
      """
      if model is None:
          raise RuntimeError(
              "Cannot calculate feature_importances without a fitted model."
              "Call `fit` first."
          )
      elif isinstance(model, ModelList):
          models = model.models
      else:
          models = [model]
      lengthscales = []
      for m in models:
          try:
              ls = m.covar_module.base_kernel.lengthscale
          except AttributeError:
              ls = None
          if ls is None or ls.shape[-1] != m.train_inputs[0].shape[-1]:
              # TODO: We could potentially set the feature importances to NaN in this
              # case, but this require knowing the batch dimension of this model.
              # Consider supporting in the future.
              raise NotImplementedError(
                  "Failed to extract lengthscales from `m.covar_module.base_kernel`"
              )
          if ls.ndim == 2:
              ls = ls.unsqueeze(0)
          if is_ensemble(
              m
          ):  # Take the median over the model batch dimension
              ls = torch.quantile(ls, q=0.5, dim=0, keepdim=True)
          lengthscales.append(ls)
      lengthscales = torch.cat(lengthscales, dim=0)
      feature_importances = (
          (1 / lengthscales).detach().cpu()
      )  # pyre-ignore
      # Make sure the sum of feature importances is 1.0 for each metric
      feature_importances /= feature_importances.sum(
          dim=-1, keepdim=True
      )
      return feature_importances.numpy()
  
imports: from __future__ import annotations
  import warnings
  from copy import deepcopy
  from logging import Logger
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import numpy
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.core.types import TCandidateMetadata
  from ax.exceptions.core import DataRequiredError
  from ax.models.torch.botorch_defaults import get_and_fit_model, get_qLogNEI, recommend_best_observed_point, scipy_optimizer, TAcqfConstructor
  from ax.models.torch.utils import _datasets_to_legacy_inputs, _get_X_pending_and_observed, _to_inequality_constraints, normalize_indices, predict_from_model, subset_model
  from ax.models.torch_base import TorchGenResults, TorchModel, TorchOptConfig
  from ax.models.types import TConfig
  from ax.utils.common.constants import Keys
  from ax.utils.common.docutils import copy_doc
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.models import ModelList
  from botorch.models.model import Model
  from botorch.utils.datasets import SupervisedDataset
  from botorch.utils.transforms import is_ensemble
  from torch import Tensor
  from torch.nn import ModuleList
label_desc: Use image node_id 2 for calling a global function with example usage: get_feature_importances_from_botorch_model(model) and returns: feature_importances