code: def save_model(
      name: Tag | str,
      model: lgb.basic.Booster,  # type: ignore (incomplete ligthgbm type stubs)
      *,
      signatures: dict[str, ModelSignatureDict] | None = None,
      labels: dict[str, str] | None = None,
      custom_objects: dict[str, t.Any] | None = None,
      external_modules: t.List[ModuleType] | None = None,
      metadata: dict[str, t.Any] | None = None,
  ) -> bentoml.Model:
      """
      Save a LightGBM model instance to the BentoML model store.
  
      Args:
          name (``str``):
              The name to give to the model in the BentoML store. This must be a valid
              :obj:`~bentoml.Tag` name.
          model (:obj:`~lgb.basic.Booster`):
              The LightGBM model (booster) to be saved.
          signatures (``dict[str, ModelSignatureDict]``, optional):
              Signatures of predict methods to be used. If not provided, the signatures default to
              ``{"predict": {"batchable": False}}``. See :obj:`~bentoml.types.ModelSignature` for more
              details.
          labels (``dict[str, str]``, optional):
              A default set of management labels to be associated with the model. An example is
              ``{"training-set": "data-1"}``.
          custom_objects (``dict[str, Any]``, optional):
              Custom objects to be saved with the model. An example is
              ``{"my-normalizer": normalizer}``.
  
              Custom objects are currently serialized with cloudpickle, but this implementation is
              subject to change.
          external_modules (:code:`List[ModuleType]`, `optional`, default to :code:`None`):
              user-defined additional python modules to be saved alongside the model or custom objects,
              e.g. a tokenizer module, preprocessor module, model configuration module
          metadata (``dict[str, Any]``, optional):
              Metadata to be associated with the model. An example is ``{"max_depth": 2}``.
  
              Metadata is intended for display in model management UI and therefore must be a default
              Python type, such as ``str`` or ``int``.
      Returns:
          :obj:`~bentoml.Tag`: A :obj:`tag` with a format `name:version` where `name` is the
          user-defined model's name, and a generated `version` by BentoML.
  
      Example:
  
      .. code-block:: python
  
          import bentoml
  
          import lightgbm as lgb
          import pandas as pd
  
          # load a dataset
          df_train = pd.read_csv("regression.train", header=None, sep="\t")
          df_test = pd.read_csv("regression.test", header=None, sep="\t")
  
          y_train = df_train[0]
          y_test = df_test[0]
          X_train = df_train.drop(0, axis=1)
          X_test = df_test.drop(0, axis=1)
  
          # create dataset for lightgbm
          lgb_train = lgb.Dataset(X_train, y_train)
          lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
  
          # specify your configurations as a dict
          params = {
              "boosting_type": "gbdt",
              "objective": "regression",
              "metric": {"l2", "l1"},
              "num_leaves": 31,
              "learning_rate": 0.05,
          }
  
          # train
          gbm = lgb.train(
              params, lgb_train, num_boost_round=20, valid_sets=lgb_eval
          )
  
          # save the booster to BentoML modelstore:
          bento_model = bentoml.lightgbm.save_model("my_lightgbm_model", gbm, booster_params=params)
      """
  
      # Ensure that `model` is actually the Booster object, and not for example one of the scikit-learn wrapper objects.
      if not isinstance(model, lgb.basic.Booster):  # type: ignore (incomplete ligthgbm type stubs)
          try:
              # Work around a LightGBM issue (https://github.com/microsoft/LightGBM/issues/3014)
              # 'model.booster_' chjecks that the model has been fitted and will error otherwise.
              if not hasattr(model, "fitted_"):  # type: ignore (incomplete ligthgbm type stubs)
                  model.fitted_ = True
  
              model = model.booster_  # type: ignore (incomplete ligthgbm type stubs)
          except AttributeError as e:
              logger.error(
                  'Unable to obtain a "lightgbm.basic.Booster" from %s.',
                  model,
              )
              raise e
  
      if not isinstance(model, lgb.basic.Booster):  # type: ignore (incomplete ligthgbm type stubs)
          raise TypeError(
              f"Given model ({model}) is not a lightgbm.basic.Booster."
          )
  
      context: ModelContext = ModelContext(
          framework_name="lightgbm",
          framework_versions={"lightgbm": get_pkg_version("lightgbm")},
      )
  
      if signatures is None:
          signatures = {
              "predict": {"batchable": False},
          }
          logger.info(
              'Using the default model signature for LightGBM (%s) for model "%s".',
              signatures,
              name,
          )
  
      with bentoml.models.create(
          name,
          module=MODULE_NAME,
          api_version=API_VERSION,
          signatures=signatures,
          labels=labels,
          custom_objects=custom_objects,
          external_modules=external_modules,
          metadata=metadata,
          context=context,
      ) as bento_model:
          model.save_model(bento_model.path_of(MODEL_FILENAME))
  
          return bento_model
  
file_path: BentoML/grpc-client/bentoml/_internal/frameworks/lightgbm.py
imports: from __future__ import annotations
  import logging
  import typing
  from types import ModuleType
  from typing import TYPE_CHECKING
  import numpy
  import bentoml
  from bentoml import Tag
  from bentoml.exceptions import InvalidArgument
  from bentoml.exceptions import MissingDependencyException
  from bentoml.exceptions import NotFound
  from ..models.model import ModelContext
  from ..utils.pkg import get_pkg_version
label_desc: Use image node_id 3 for calling a global function with example usage: save_model(name, model) and returns: bento_model