code: def _verify_lm_lora_finetuning_layers(
      attention_layer: torch.nn.Module,
      target_modules: set[str],
      merge_adapter_into_base_model: bool,
      model_weights_directory: str,
      expected_lora_in_features: int,
      expected_lora_out_features: int,
      expected_file_names: list[str],
  ) -> None:
      """This method verifies that LoRA finetuning layers have correct types and shapes, depending on whether the
      optional "model.merge_and_unload()" method (based on the "merge_adapter_into_base_model" directive) was
      executed.
  
      If merge_adapter_into_base_model is True, then all specified LoRA projection layers in the attention layer must
      contain square weight matrices (with the dimensions expected_lora_in_features by expected_lora_in_features).
      However, if merge_adapter_into_base_model is False, then the LoRA part of the attention layer must include Lora_A
      and Lora_B children layers for each specified projection, such that the product of Lora_A and Lora_B is a square
      matrix (with the dimensions expected_lora_in_features by expected_lora_in_features) for each specified projection.
      """
      from peft.tuners.lora.layer import LoraLayer
  
      expected_lora_num_features_orig: tuple[int] = (
          expected_lora_in_features,
          expected_lora_out_features,
      )
  
      file_names: list[str] = list_file_names_in_directory(
          directory_name=model_weights_directory
      )
      assert set(file_names) == set(expected_file_names)
  
      target_module_name: str
      target_module_obj: LoraLayer | torch.nn.Linear
  
      # Not providing default value to "getattr()" so that error is raised if incorrect projection layer name is supplied.
  
      for target_module_name in target_modules:
          target_module_obj = getattr(
              attention_layer, target_module_name
          )
          if merge_adapter_into_base_model:
              assert isinstance(target_module_obj, torch.nn.Linear)
          else:
              assert isinstance(target_module_obj, LoraLayer)
  
      if merge_adapter_into_base_model:
          # If LoRA A & B layers are merged, they must have no children layers, and projection matrices must be square.
          for target_module_name in target_modules:
              target_module_obj = getattr(
                  attention_layer, target_module_name
              )
              assert not list(target_module_obj.children())
              assert (
                  target_module_obj.in_features,
                  target_module_obj.out_features,
              ) == (
                  expected_lora_in_features,
                  expected_lora_out_features,
              )
      else:
          # If LoRA A & B layers are not merged, their children layers must be correctly-dimensioned projection matrices.
          expected_lora_num_features: tuple[int]
          target_named_children: dict[str, torch.nn.Module]
          lora_matrix_name: str
          idx: int
          for target_module_name in target_modules:
              target_module_obj = getattr(
                  attention_layer, target_module_name
              )
              target_named_children = dict(
                  target_module_obj.named_children()
              )
  
              for idx, lora_matrix_name in enumerate(
                  ["lora_A", "lora_B"]
              ):
                  assert isinstance(
                      target_named_children[lora_matrix_name][
                          "default"
                      ],
                      torch.nn.Linear,
                  )
  
                  # LoRA A and B matrix dimensions are transposes of one another so that their product is square matrix.
                  expected_lora_num_features = (
                      expected_lora_num_features_orig
                      if idx % 2 == 0
                      else (
                          expected_lora_num_features_orig[1],
                          expected_lora_num_features_orig[0],
                      )
                  )
                  assert (
                      target_named_children[lora_matrix_name][
                          "default"
                      ].in_features,
                      target_named_children[lora_matrix_name][
                          "default"
                      ].out_features,
                  ) == expected_lora_num_features
  
imports: from __future__ import annotations
  import copy
  import json
  import os
  import pathlib
  from typing import Any
  import numpy
  import pandas
  import pytest
  import torch
  import ludwig.error
  from ludwig.api import LudwigModel
  from ludwig.constants import ADAPTER, BACKEND, BASE_MODEL, BATCH_SIZE, COMBINER, EPOCHS, GENERATION, INPUT_FEATURES, MERGE_ADAPTER_INTO_BASE_MODEL, MODEL_ECD, MODEL_LLM, MODEL_TYPE, OUTPUT_FEATURES, POSTPROCESSOR, PREPROCESSING, PRETRAINED_ADAPTER_WEIGHTS, PROGRESSBAR, PROMPT, QUANTIZATION, TARGET_MODULES, TRAINER, TYPE
  from ludwig.models.llm import LLM
  from ludwig.schema.model_types.base import ModelConfig
  from ludwig.utils.fs_utils import list_file_names_in_directory
  from ludwig.utils.types import DataFrame
  from tests.integration_tests.utils import category_feature, generate_data, text_feature
label_desc: Use image node_id 12 for calling a global function with example usage: _verify_lm_lora_finetuning_layers(attention_layer, target_modules, merge_adapter_into_base_model, model_weights_directory, expected_lora_in_features, expected_lora_out_features, expected_file_names) without return types