본문 바로가기
AI 빅데이터/AI 동향

[LangChain] Vertex AI의 PaLM으로 LangChain QA하기

by 마고커 2023. 6. 25.


지난번 포스팅에서는 OpenAI의 GPT-3.5로 QA 하는 보았다.

 

 

[LangChain] GPT로 Summary와 QA 해 보기

LangChain은 LLM을 App에서 활용할 수 있게 해 주는 도구다. GPT-3나 BLOOM과 같은 초거대AI에게 질의해서 결과를 가져와 App을 구성할 수 있다. LangChain의 컴퍼넌트들은 기회될 때 보기로 하고, 여기서는

magoker.tistory.com

 

GPT API는 요금이 발생하기 때문에 자유롭게 테스트하기 어렵다. Vertex AI의 PaLM은 아직(정보에 의하면 6월말까지는 확실히) 무료라고 한다. 마침 LangChain에서 VertexAI PaLM 지원을 해 주었기 때문에 LLM 애플리케이션에 도움이 될 듯하다.

 

 

Google Cloud Platform Vertex AI PaLM | 🦜️🔗 Langchain

Note: This is seperate from the Google PaLM integration. Google has chosen to offer an enterprise version of PaLM through GCP, and this supports the models made available through there.

python.langchain.com

 

본 포스팅에서 아래의 문서를 참조했다.

 

GitHub - GoogleCloudPlatform/generative-ai: Sample code and notebooks for Generative AI on Google Cloud

Sample code and notebooks for Generative AI on Google Cloud - GitHub - GoogleCloudPlatform/generative-ai: Sample code and notebooks for Generative AI on Google Cloud

github.com

 

여기서는 웹 주소에서 문서를 가져다가 VectorStore에 저장하고 거기서 Query하는 것을 해보려고 한다. 우선 필요한 패키지들을 설치 해 주고

 

! pip install google-cloud-aiplatform langchain pandas datasets google-api-python-client chromadb pypdf faiss-cpu faiss-cpu transformers config --upgrade --user

 

VertexAI를 Python에서 사용하기 위해서 GCP인증을 한다. 주의할 점은 colab과 gcp의 계정명이 같아야 한다. GCP에서 사용하는 Project 명과 함께 vertexai를 초기화 해 준다. 

 

from google.colab import auth as google_auth
google_auth.authenticate_user()

import vertexai

PROJECT_ID = "너의 GCP 프로젝트명"  # @param {type:"string"}
vertexai.init(project=PROJECT_ID, location="us-central1")

 

VertexAI PaLM 모델을 초기화한다. 다른 LLM 사용하는 경우와 크게 다르지 않으므로 설명은 넘어간다. 아울러 Vector 저장을 위해 embedding을 custom하게 구성했다. LangChain에서 기본 package로 지원하는 SentenceTransformerEmbeddings를 사용해보기도 했으나 성능이 좋지 않아 예제로 준 코드를 그대로 사용했다. 임베딩 설정에 대해서는 더 공부가 필요할 듯.

 

import langchain
from langchain.embeddings import VertexAIEmbeddings

import time

# Utility functions for Embeddings API with rate limiting
def rate_limit(max_per_minute):
    period = 60 / max_per_minute
    print("Waiting")
    while True:
        before = time.time()
        yield
        after = time.time()
        elapsed = after - before
        sleep_time = max(0, period - elapsed)
        if sleep_time > 0:
            print(".", end="")
            time.sleep(sleep_time)

class CustomVertexAIEmbeddings(VertexAIEmbeddings, BaseModel):
    requests_per_minute: int
    num_instances_per_batch: int

    # Overriding embed_documents method
    def embed_documents(self, texts: List[str]):
        limiter = rate_limit(self.requests_per_minute)
        results = []
        docs = list(texts)

        while docs:
            # Working in batches because the API accepts maximum 5
            # documents per request to get embeddings
            head, docs = (
                docs[: self.num_instances_per_batch],
                docs[self.num_instances_per_batch :],
            )
            chunk = self.client.get_embeddings(head)
            results.extend(chunk)
            next(limiter)

        return [r.values for r in results]

# LLM model
llm = VertexAI(
    model_name="text-bison@001",
    max_output_tokens=256,
    temperature=0.1,
    top_p=0.8,
    top_k=40,
    verbose=True,
)

# Embedding
EMBEDDING_QPM = 100
EMBEDDING_NUM_BATCH = 5
embeddings = CustomVertexAIEmbeddings(
    requests_per_minute=EMBEDDING_QPM,
    num_instances_per_batch=EMBEDDING_NUM_BATCH,
)

 

웹에서 문서를 읽어서 파싱하고 LLM이 처리할 수 있는 크기로 Text를 분리한다. chunk_size는 문서의 최대 크기(토큰 수)를 나타내는데 PaLM이 4,000자까지 지원하므로 지정하지 않으면 4,000이 된다. 여기서는 1,500으로 했고, 각 chunk(문서)들이 종종 이상하게 분할되는 것을 방지하는 chunk_overlap은 0(별 고려 없이 분할)으로 했다. 아래의 삼성전자 리포트는 약 913개의 문서로 구분될 것이다.

 

# Ingest PDF files
from langchain.document_loaders import PyPDFLoader

# 삼성전자의 22년 4Q 사업보고서 자료
url = "https://images.samsung.com/is/content/samsung/assets/global/ir/docs/2022-4q-Business-Report.pdf"
loader = PyPDFLoader(url)
documents = loader.load()

# split the documents into chunks
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
print(f"# of documents = {len(docs)}")

 

Vector Store인 Chroma에 읽어들인 문서를 embedding하여 저장한다.

 

# Store docs in local vectorstore as index
# it may take a while since API is rate limited
from langchain.vectorstores import Chroma

db = Chroma.from_documents(docs, embeddings)

 

Chroma DB에서 유사도 검사를 통해 QA를 실시하도록 Setting한다.

 

# Expose index to the retriever
retriever = db.as_retriever(search_type="similarity", search_kwargs={"k": 3})

# Create chain to answer questions
from langchain.chains import RetrievalQA

# Uses LLM to synthesize results from the search index.
# We use Vertex PaLM Text API for LLM
qa = RetrievalQA.from_chain_type(
    llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=False
)

 

대체로 영어로 질문할 때 좋은 결과를 얻지만, 한글 질문으로도 결과를 얻을 수 있었다.

 

query = "삼성전자의 사업부는 어떻게 구성되어 있어?"
result = qa({"query": query})
print(result)
llm(result['result'])

 

위의 RetrialQA.from_chain_type설정에서 return_source_documents를 False로 두었는데 True로 바꾸면 대답의 원천을 확인할 수 있다. 여기서는 skip. 삼성전자 Division을 잘 구분해주었다.

 

{'query': '삼성전자의 사업부는 어떻게 구성되어 있어?', 'result': 'The business units of Samsung Electronics are as follows: DX Division, MX Division, DS Division, and CT Division.'}
\n\n* DX Division (Digital Appliances & Solutions): This division includes the home appliance business, which produces refrigerators, washing machines, air conditioners, and other home appliances. It also includes the visual display business, which produces televisions, monitors, and other display devices.\n* MX Division (Mobile Experience): This division includes the mobile phone business, which produces smartphones, tablets, and other mobile devices. It also includes the wearables business, which produces smartwatches and fitness trackers.\n* DS Division (Device Solutions): This division includes the semiconductor business, which produces memory chips, flash memory, and other semiconductor products. It also includes the display business, which produces OLED displays and other display products.\n* CT Division (Consumer Electronics): This division includes the audio and video business, which produces home theater systems, Blu-ray players, and other audio and video products. It also inc

 

다른 한글 질문에는 이상한 답을 한다. 영어 질문에는 원했던 것은 아니지만 비교적 유사하게 대답한다.

 

query = "모바일 패널 사업의 기술적 차별점은 뭐니?"
result = qa({"query": query})
print(result)
llm(result['result'])

---

{'query': '모바일 패널 사업의 기술적 차별점은 뭐니?', 'result': 'Ultra -thin glass technology allows foldable glass display —a first among Galaxy models —and enhances durability'}
The Galaxy Z Fold3 5G features a new ultra-thin glass (UTG) that is thinner than previous models, while still being durable enough to withstand everyday use. This new UTG is made with a new material that is stronger and more resistant to scratches and cracks. It also has a new coating that helps to reduce fingerprints and smudges.

 

영어 질문에는 원했던 것은 아니지만 비교적 유사하게 대답한다.

 

The mobile panel business achieved solid earnings, led mainly by high-end products, despite a decline in smartphone demand due to weakened consumer sentiment caused by concerns over inflation, rate hikes, and the economic downturn. We actively addressed our customers’ increasingly sophisticated needs by establishing an optimal product portfolio that ranges from mass-market through to premium products with our Flexible and Rigid OLED panels. Indeed, our industry-leading technological capabilities have been recognized based on our products’ differentiated technologies and performance.

 

아직은 된다는 것에 중점을 두어야 할 것 같다.



댓글