code: def apply_layerwise_lr_decay(
      model: nn.Module,
      lr: float,
      lr_decay: float,
      weight_decay: float,
      efficient_finetune: Optional[str] = None,
      trainable_param_names: Optional[List] = None,
  ):
      """
      Assign monotonically decreasing learning rates for layers from the output end to the input end.
      The intuition behind is that later layers are more task-related compared to the early layers.
      Layer normalization parameters and other layers' bias parameters don't use weight decay.
      If you want to double-check whether the learning rate setup is as expected,
      you can print the layer names along with their learning rates through
      "print("Param groups = %s" % json.dumps(parameter_group_names, indent=2))".
  
      Parameters
      ----------
      model
          A Pytorch model.
      lr
          The learning rate.
      lr_decay
          The learning rate decay factor (0, 1).
      weight_decay
          Weight decay.
      efficient_finetune
          Efficient finetuning strategy. It will only finetune part of the parameters
  
      Returns
      -------
      The grouped parameters based on their layer ids and whether using weight decay.
      """
      parameter_group_names = {}
      parameter_group_vars = {}
      decay_param_names = get_weight_decay_param_names(model)
  
      for name, param in model.named_parameters():
          if name.startswith("_orig_mod."):
              name = "".join(name.split("_orig_mod."))
          layer_id = model.name_to_id[name]
          if (
              layer_id == 0
          ):  # Set top layer (e.g. head, fusion_mlp, adapter) as being trainable.
              param.requires_grad = True
          elif (
              efficient_finetune is not None
              and efficient_finetune != "None"
              and trainable_param_names
              and not any(
                  [
                      re.match(trainable_param_name, name)
                      for trainable_param_name in trainable_param_names
                  ]
              )
          ):
              param.requires_grad = False
  
          if not param.requires_grad:
              continue  # frozen weights
  
          if name in decay_param_names:
              group_name = "decay"
              this_weight_decay = weight_decay
          else:
              group_name = "no_decay"
              this_weight_decay = 0.0
  
          layer_id = model.name_to_id[name]
          group_name = "layer_%d_%s" % (layer_id, group_name)
  
          if group_name not in parameter_group_names:
              scale = lr_decay**layer_id
              parameter_group_names[group_name] = {
                  "weight_decay": this_weight_decay,
                  "params": [],
                  "lr": scale * lr,
              }
              parameter_group_vars[group_name] = {
                  "weight_decay": this_weight_decay,
                  "params": [],
                  "lr": scale * lr,
              }
  
          parameter_group_vars[group_name]["params"].append(param)
          parameter_group_names[group_name]["params"].append(name)
  
      return list(parameter_group_vars.values())
  
imports: import functools
  import logging
  import re
  import warnings
  from typing import Any, Dict, List, Optional, Tuple, Union
  import torch
  import torchmetrics
  from omegaconf import DictConfig, OmegaConf
  from packaging import version
  from pytorch_metric_learning import distances, losses, miners
  from torch import nn, optim
  from torch.nn import functional
  from torchmetrics.detection.mean_ap import MeanAveragePrecision
  from transformers import Adafactor
  from transformers.models.mask2former.modeling_mask2former import Mask2FormerConfig, Mask2FormerLoss
  from transformers.trainer_pt_utils import get_parameter_names
  from ..constants import ACC, ACCURACY, AVERAGE_PRECISION, BER, BINARY, BIT_FIT, COLUMN_FEATURES, CONTRASTIVE_LOSS, COSINE_EMBEDDING_LOSS, COSINE_SIMILARITY, CROSS_ENTROPY, DETECTION_METRICS, DIRECT_LOSS, EM, F1, F1_MACRO, F1_MICRO, F1_WEIGHTED, FEATURES, FEW_SHOT_CLASSIFICATION, FM, HIT_RATE, IA3, IA3_BIAS, IA3_LORA, IA3_LORA_BIAS, IA3_LORA_NORM, IA3_NORM, IOU, LOG_LOSS, LORA, LORA_BIAS, LORA_NORM, MAE, MULTI_NEGATIVES_SOFTMAX_LOSS, MULTICLASS, NER, NER_TOKEN_F1, NORM_FIT, OBJECT_DETECTION, OPEN_VOCABULARY_OBJECT_DETECTION, OVERALL_ACCURACY, PAIR_MARGIN_MINER, PEARSONR, PEFT_STRATEGIES, QUADRATIC_KAPPA, R2, RECALL, REGRESSION, RMSE, ROC_AUC, ROOT_MEAN_SQUARED_ERROR, SEMANTIC_SEGMENTATION, SM, SPEARMANR
  from .losses import BBCEWithLogitLoss, FocalLoss, MultiNegativesSoftmaxLoss, SoftTargetCrossEntropy, StructureLoss
  from .lr_scheduler import get_cosine_schedule_with_warmup, get_linear_schedule_with_warmup, get_polynomial_decay_schedule_with_warmup
  from .semantic_seg_metrics import COD_METRICS_NAMES, Balanced_Error_Rate, Binary_IoU, Multiclass_IoU
label_desc: Use image node_id 12 for calling a global function with example usage: apply_layerwise_lr_decay(model, lr, lr_decay, weight_decay, efficient_finetune, trainable_param_names) and returns: list