code: def check_hyperopt_nested_parameter_dicts(
      config: "ModelConfig",
  ) -> None:  # noqa: F821
      """Checks that all nested parameters in a hyperopt config exist."""
      if (
          config.hyperopt is None
          or "." not in config.hyperopt.parameters
      ):
          return
  
      from ludwig.schema.hyperopt.utils import (
          get_parameter_cls,
      )  # noqa: F401
      from ludwig.schema.model_types.base import ModelConfig
  
      space = config.hyperopt.parameters["."]
  
      # Build the config that would be produced by each parameter dict to validate subsections that may be in
      config_dict = config.to_dict()
      del config_dict["hyperopt"]
      for category in space["categories"]:
          for i, k in enumerate(category.keys()):
              try:
                  config.__getattribute__(k)
              except AttributeError:
                  raise ConfigValidationError(
                      f"Invalid config block {k} in nested hyperopt parameter dict {i}: {space}."
                  )
  
          category_dict = merge_dict(config_dict, category)
          try:
              ModelConfig.from_dict(category_dict)
          except ConfigValidationError as e:
              raise ConfigValidationError(
                  f"Invalid config in hyperopt nested parameter config: {category}. {e.message}"
              )
  
      try:
          space_cls = get_parameter_cls("choice")
          space_cls.from_dict(space)
      except KeyError:
          raise ConfigValidationError(
              f"Nested hyperparameter search spaces must be of type 'choice'. Requested space type: {space['space']}"
          )
  
imports: from abc import ABC, abstractmethod
  from re import findall
  from typing import Callable, TYPE_CHECKING
  from transformers import AutoConfig
  from ludwig.api_annotations import DeveloperAPI
  from ludwig.constants import AUDIO, BINARY, CATEGORY, IMAGE, IN_MEMORY, MIN_QUANTIZATION_BITS_FOR_MERGE_AND_UNLOAD, MODEL_ECD, MODEL_GBM, MODEL_LLM, NUMBER, SEQUENCE, SET, TEXT, TIMESERIES, VECTOR
  from ludwig.error import ConfigValidationError
  from ludwig.utils.metric_utils import get_feature_to_metric_names_map_from_feature_collection
  from ludwig.utils.misc_utils import merge_dict
label_desc: Use image node_id 23 for calling a global function with example usage: check_hyperopt_nested_parameter_dicts(config) without return types