code: def get_runnable(
      bento_model: bentoml.Model,
  ):
      """
      Private API: use :obj:`~bentoml.Model.to_runnable` instead.
      """
  
      partial_kwargs: t.Dict[
          str, t.Any
      ] = bento_model.info.options.partial_kwargs
  
      class TensorflowRunnable(Runnable):
          SUPPORTED_RESOURCES = ("nvidia.com/gpu", "cpu")
          SUPPORTS_CPU_MULTI_THREADING = True
  
          def __init__(self):
              super().__init__()
              if len(tf.config.list_physical_devices("GPU")) > 0:
                  # In Multi-GPU scenarios, the visible cuda devices will be set for each Runner worker
                  # by the runner's Scheduling Strategy. So that the Runnable implementation only needs
                  # to find the first GPU device visible to current process.
                  self.device_name = "/device:GPU:0"
              else:
                  self.device_name = "/device:CPU:0"
  
              self.model = load_model(
                  bento_model, device_name=self.device_name
              )
              self.methods_cache: t.Dict[
                  str, t.Callable[..., t.Any]
              ] = {}
              self.session_stack = contextlib.ExitStack()
              self.session_stack.enter_context(
                  tf.device(self.device_name)
              )
  
          def __del__(self):
              try:
                  self.session_stack.close()
              except RuntimeError:
                  pass
  
      def _gen_run_method(
          runnable_self: TensorflowRunnable, method_name: str
      ):
          raw_method = getattr(runnable_self.model, method_name)
          method_partial_kwargs = partial_kwargs.get(method_name)
  
          output_sigs = get_output_signatures_v2(raw_method)
  
          if len(output_sigs) == 1:
              # if there's only one output signatures, then we can
              # define the _postprocess function without doing
              # conditional casting each time
  
              sig = output_sigs[0]
              if isinstance(sig, (list, tuple)):
  
                  def _postprocess(
                      res: tuple[tf_ext.EagerTensor],
                  ) -> TFRunnableOutputType:
                      return tuple(
                          t.cast("ext.NpNDArray", r.numpy())
                          for r in res
                      )
  
              else:
  
                  def _postprocess(
                      res: tf_ext.EagerTensor,
                  ) -> TFRunnableOutputType:
                      return t.cast("ext.NpNDArray", res.numpy())
  
          else:
              # if there are no output signature or more than one output
              # signatures, the post process function need to do casting
              # depends on the real output value each time
  
              def _postprocess(
                  res: TFModelOutputType,
              ) -> TFRunnableOutputType:
                  if isinstance(res, (tuple, list)):
                      return tuple(
                          t.cast("ext.NpNDArray", r.numpy())
                          for r in res
                      )
                  else:
                      return t.cast("ext.NpNDArray", res.numpy())
  
          def _run_method(
              _runnable_self: TensorflowRunnable,
              *args: TFArgType,
              **kwargs: TFArgType,
          ) -> TFRunnableOutputType:
              if method_partial_kwargs is not None:
                  kwargs = dict(method_partial_kwargs, **kwargs)
  
              try:
                  res = raw_method(*args, **kwargs)
              except ValueError:
                  # Tensorflow performs type checking implicitly if users decorate with `tf.function
                  # or provide `tf_signatures` when calling `save_model()`. Type checking and
                  # casting is deferred to after the `ValueError` is raised to optimize performance.
                  sigs = get_input_signatures_v2(raw_method)
                  if not sigs:
                      raise
  
                  try:
                      casted_args = cast_py_args_to_tf_function_args(
                          sigs[0], *args, **kwargs
                      )
                  except ValueError:
                      raise
  
                  res = raw_method(*casted_args)
              return _postprocess(res)
  
          return _run_method
  
      def add_run_method(method_name: str, options: ModelSignature):
          def run_method(
              runnable_self: TensorflowRunnable,
              *args: TFArgType,
              **kwargs: TFArgType,
          ) -> TFRunnableOutputType:
              _run_method = runnable_self.methods_cache.get(
                  method_name
              )  # is methods_cache nessesary?
              if not _run_method:
                  _run_method = _gen_run_method(
                      runnable_self, method_name
                  )
                  runnable_self.methods_cache[method_name] = _run_method
  
              return _run_method(runnable_self, *args, **kwargs)
  
          TensorflowRunnable.add_method(
              run_method,
              name=method_name,
              batchable=options.batchable,
              batch_dim=options.batch_dim,
              input_spec=options.input_spec,
              output_spec=options.output_spec,
          )
  
      for method_name, options in bento_model.info.signatures.items():
          add_run_method(method_name, options)
  
      return TensorflowRunnable
  
imports: from __future__ import annotations
  import contextlib
  import itertools
  import logging
  import pickle
  import typing
  from types import ModuleType
  from typing import TYPE_CHECKING
  import bentoml
  from bentoml import Runnable
  from bentoml import Tag
  from bentoml.exceptions import MissingDependencyException
  from bentoml.exceptions import NotFound
  from bentoml.models import ModelContext
  from ..models.model import ModelSignature
  from ..models.model import PartialKwargsModelOptions
  from ..runner.container import DataContainer
  from ..runner.container import DataContainerRegistry
  from ..runner.container import Payload
  from ..types import LazyType
  from .utils.tensorflow import cast_py_args_to_tf_function_args
  from .utils.tensorflow import get_input_signatures_v2
  from .utils.tensorflow import get_output_signatures_v2
  from .utils.tensorflow import get_restorable_functions
  from .utils.tensorflow import get_tf_version
label_desc: Use image node_id 4 for calling a global function with example usage: get_runnable(bento_model) and returns: TensorflowRunnable, _run_method, _postprocess, _run_method, tuple, t, tuple, t