code: #
  # Copyright 2016 The BigDL Authors.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  # This would makes sure Python is aware there is more than one sub-package within bigdl,
  # physically located elsewhere.
  # Otherwise there would be module not found error in non-pip's setting as Python would
  # only search the first bigdl package and end up finding only one sub-package.
  
  # This file is adapted from
  # https://github.com/hwchase17/langchain/blob/master/langchain/llms/huggingface_pipeline.py
  
  # The MIT License
  
  # Copyright (c) Harrison Chase
  
  # Permission is hereby granted, free of charge, to any person obtaining a copy
  # of this software and associated documentation files (the "Software"), to deal
  # in the Software without restriction, including without limitation the rights
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  # copies of the Software, and to permit persons to whom the Software is
  # furnished to do so, subject to the following conditions:
  
  # The above copyright notice and this permission notice shall be included in
  # all copies or substantial portions of the Software.
  
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  # THE SOFTWARE.
  
  
  import importlib.util
  import logging
  from typing import Any, List, Mapping, Optional
  
  from pydantic import Extra
  
  from langchain.callbacks.manager import CallbackManagerForLLMRun
  from langchain.llms.base import LLM
  from langchain.llms.utils import enforce_stop_tokens
  
  DEFAULT_MODEL_ID = "gpt2"
  DEFAULT_TASK = "text-generation"
  VALID_TASKS = ("text2text-generation", "text-generation", "summarization")
  
  
  class TransformersPipelineLLM(LLM):
      """Wrapper around the BigDL-LLM Transformer-INT4 model in Transformer.pipeline()
  
      Example:
          .. code-block:: python
  
              from bigdl.llm.langchain.llms import TransformersPipelineLLM
              llm = TransformersPipelineLLM.from_model_id(model_id="decapoda-research/llama-7b-hf")
      """
  
      pipeline: Any  #: :meta private:
      model_id: str = DEFAULT_MODEL_ID
      """Model name or model path to use."""
      model_kwargs: Optional[dict] = None
      """Key word arguments passed to the model."""
      pipeline_kwargs: Optional[dict] = None
      """Key word arguments passed to the pipeline."""
  
      class Config:
          """Configuration for this pydantic object."""
  
          extra = Extra.forbid
  
      @classmethod
      def from_model_id(
          cls,
          model_id: str,
          task: str,
          model_kwargs: Optional[dict] = None,
          pipeline_kwargs: Optional[dict] = None,
          **kwargs: Any,
      ) -> LLM:
          """Construct the pipeline object from model_id and task."""
          try:
              from bigdl.llm.transformers import (
                  AutoModel,
                  AutoModelForCausalLM,
                  # AutoModelForSeq2SeqLM,
              )
              from transformers import AutoTokenizer, LlamaTokenizer
              from transformers import pipeline as hf_pipeline
  
          except ImportError:
              raise ValueError(
                  "Could not import transformers python package. "
                  "Please install it with `pip install transformers`."
              )
  
          _model_kwargs = model_kwargs or {}
          # TODO: may refactore this code in the future
          try:
              tokenizer = AutoTokenizer.from_pretrained(model_id, **_model_kwargs)
          except:
              tokenizer = LlamaTokenizer.from_pretrained(model_id, **_model_kwargs)
  
          try:
              if task == "text-generation":
                  model = AutoModelForCausalLM.from_pretrained(model_id, load_in_4bit=True, **_model_kwargs)
              elif task in ("text2text-generation", "summarization"):
                  # TODO: support this when related PR merged
                  model = AutoModelForSeq2SeqLM.from_pretrained(model_id, load_in_4bit=True, **_model_kwargs)
              else:
                  raise ValueError(
                      f"Got invalid task {task}, "
                      f"currently only {VALID_TASKS} are supported"
                  )
          except ImportError as e:
              raise ValueError(
                  f"Could not load the {task} model due to missing dependencies."
              ) from e
  
          if "trust_remote_code" in _model_kwargs:
              _model_kwargs = {
                  k: v for k, v in _model_kwargs.items() if k != "trust_remote_code"
              }
          _pipeline_kwargs = pipeline_kwargs or {}
          pipeline = hf_pipeline(
              task=task,
              model=model,
              tokenizer=tokenizer,
              device='cpu',  # only cpu now
              model_kwargs=_model_kwargs,
              **_pipeline_kwargs,
          )
          if pipeline.task not in VALID_TASKS:
              raise ValueError(
                  f"Got invalid task {pipeline.task}, "
                  f"currently only {VALID_TASKS} are supported"
              )
          return cls(
              pipeline=pipeline,
              model_id=model_id,
              model_kwargs=_model_kwargs,
              pipeline_kwargs=_pipeline_kwargs,
              **kwargs,
          )
  
      @property
      def _identifying_params(self) -> Mapping[str, Any]:
          """Get the identifying parameters."""
          return {
              "model_id": self.model_id,
              "model_kwargs": self.model_kwargs,
              "pipeline_kwargs": self.pipeline_kwargs,
          }
  
      @property
      def _llm_type(self) -> str:
          return "BigDL-llm"
  
      def _call(
          self,
          prompt: str,
          stop: Optional[List[str]] = None,
          run_manager: Optional[CallbackManagerForLLMRun] = None,
          **kwargs: Any,
      ) -> str:
          response = self.pipeline(prompt)
          if self.pipeline.task == "text-generation":
              # Text generation return includes the starter text.
              text = response[0]["generated_text"][len(prompt) :]
          elif self.pipeline.task == "text2text-generation":
              text = response[0]["generated_text"]
          elif self.pipeline.task == "summarization":
              text = response[0]["summary_text"]
          else:
              raise ValueError(
                  f"Got invalid task {self.pipeline.task}, "
                  f"currently only {VALID_TASKS} are supported"
              )
          if stop is not None:
              # This is a bit hacky, but I can't figure out a better way to enforce
              # stop tokens when making calls to huggingface_hub.
              text = enforce_stop_tokens(text, stop)
          return text
  
apis: langchain.llms.utils.enforce_stop_tokens
extract_api: [((5354, 5476), 'transformers.pipeline', 'hf_pipeline', ([], {'task': 'task', 'model': 'model', 'tokenizer': 'tokenizer', 'device': '"""cpu"""', 'model_kwargs': '_model_kwargs'}), "(task=task, model=model, tokenizer=tokenizer, device='cpu',\n    model_kwargs=_model_kwargs, **_pipeline_kwargs)\n", (5365, 5476), True, 'from transformers import pipeline as hf_pipeline\n'), ((4206, 4262), 'transformers.AutoTokenizer.from_pretrained', 'AutoTokenizer.from_pretrained', (['model_id'], {}), '(model_id, **_model_kwargs)\n', (4235, 4262), False, 'from transformers import AutoTokenizer, LlamaTokenizer\n'), ((7329, 7360), 'langchain.llms.utils.enforce_stop_tokens', 'enforce_stop_tokens', (['text', 'stop'], {}), '(text, stop)\n', (7348, 7360), False, 'from langchain.llms.utils import enforce_stop_tokens\n'), ((4303, 4360), 'transformers.LlamaTokenizer.from_pretrained', 'LlamaTokenizer.from_pretrained', (['model_id'], {}), '(model_id, **_model_kwargs)\n', (4333, 4360), False, 'from transformers import AutoTokenizer, LlamaTokenizer\n'), ((4441, 4528), 'bigdl.llm.transformers.AutoModelForCausalLM.from_pretrained', 'AutoModelForCausalLM.from_pretrained', (['model_id'], {'load_in_4bit': '(True)'}), '(model_id, load_in_4bit=True, **\n    _model_kwargs)\n', (4477, 4528), False, 'from bigdl.llm.transformers import AutoModel, AutoModelForCausalLM\n')]