본문 바로가기
연구노트

On-Premises Llama 2 및 SingleStoreDB 를 이용한 생성형 AI 프로그램 예제

by 에이플랫폼 [Team SingleStore Korea] 2023. 10. 12.
이번 글에서는 On-Premises 환경에서 Llama 2 및 SingleStoreDB 를 각각 LLM 및 Vector Store 로 사용하는 간단한 예제를 소개하려고 합니다.

 

Llama 는 Meta 에서 공개한 Open LLM 으로 API 를 이용하는 OpenAI 의 ChatGPT 와 달리 온프레미스에서 로컬 서버에 설치가 가능해 많은 인기를 누리고 있습니다.

 

예제에서는 GPU 없이 CPU 만으로도 모델을 실행해 볼 수 있도록 양자화된 작은 크기의 Llama 모델을 사용할 것이며

Embedding 모델 역시 HuggingFace 에서 많이 사용하는 일반적인 모델을 이용할 것입니다.

 

전체적으로는 Python 의 langchain 패키지를 이용해 예제를 구성할 것이며 내용은 다음 SingleStore 의 Webinar 에서 발표했던 내용을 참조하고 있습니다.

https://github.com/singlestore-labs/webinar-code-examples/tree/main/llama-2-local

 

이번 예제의 데이터 흐름은 다음과 같습니다.

ㆍ Document 를 Chunk 단위로 나누어 SingleStoreDB 의 Vector Embedding 으로 저장해 놓습니다.

ㆍ 사용자의 질의는 Embedding 하여 SingleStoreDB 에서 KNN 유사도 검색을 통해 Data Text Chunk 로 반환받습니다.

ㆍ 원래 사용자 질의와 반환 받은 Data Context 를 함께 Llama 2 LLM 에 전달합니다.

ㆍ Llama 2 LLM 으로부터 받은 답변을 출력합니다.

 

1) Llama 2 모델 다운로드 및 테스트

Linux 에서 Llama 2 모델을 실행하기 위한 환경인 llama.cpp 를 설치합니다. 최근 버전의 경우 GGML을 사용할 수 없기 때문에 이전 버전으로 Git Branch 를 reset 해야 합니다.

파라미터 7B 짜리 Llama 2 모델 하나를 다운로드 받고 필요한 경우 g++ 컴파일러도 설치합니다.

 

 

$ git clone https://github.com/ggerganov/llama.cpp
$ cd llama.cpp
$ git reset --hard dadbed99e65252d79f81101a392d0d6497b86caa
$ curl -L "https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML/resolve/main/llama-2-7b-chat.ggmlv3.q4_K_S.bin" -o models/llama-2-7b-chat.ggmlv3.q4_K_S.bin

$ sudo yum install -y gcc-c++
$ make

 

 

컴파일이 정상적으로 끝났으면 Llama LLM 에 질의를 전달해 봅니다.

2023 년 현재 태풍 카눈과 잼버리 대회와의 관계에 대해 물어 보겠습니다.

 

 

$ ./main -m ./models/llama-2-7b-chat.ggmlv3.q4_K_S.bin -p "Tell me about the relations between Typhoon Khanun and Jamboree in South Korea" -n 512
main: build = 972 (916a9ac)
main: seed  = 1691717729
llama.cpp: loading model from ./models/llama-2-7b-chat.ggmlv3.q4_K_S.bin
llama_model_load_internal: format     = ggjt v3 (latest)
llama_model_load_internal: n_vocab    = 32000
llama_model_load_internal: n_ctx      = 512
llama_model_load_internal: n_embd     = 4096
llama_model_load_internal: n_mult     = 256
llama_model_load_internal: n_head     = 32
llama_model_load_internal: n_head_kv  = 32
llama_model_load_internal: n_layer    = 32
llama_model_load_internal: n_rot      = 128
llama_model_load_internal: n_gqa      = 1
llama_model_load_internal: rnorm_eps  = 5.0e-06
llama_model_load_internal: n_ff       = 11008
llama_model_load_internal: freq_base  = 10000.0
llama_model_load_internal: freq_scale = 1
llama_model_load_internal: ftype      = 14 (mostly Q4_K - Small)
llama_model_load_internal: model size = 7B
llama_model_load_internal: ggml ctx size =    0.08 MB
llama_model_load_internal: mem required  = 3647.96 MB (+  256.00 MB per state)
llama_new_context_with_model: kv self size  =  256.00 MB
llama_new_context_with_model: compute buffer total size =   71.84 MB

system_info: n_threads = 4 / 4 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 0 | VSX = 0 |
sampling: repeat_last_n = 64, repeat_penalty = 1.100000, presence_penalty = 0.000000, frequency_penalty = 0.000000, top_k = 40, tfs_z = 1.000000, top_p = 0.950000, typical_p = 1.000000, temp = 0.800000, mirostat = 0, mirostat_lr = 0.100000, mirostat_ent = 5.000000
generate: n_ctx = 512, n_batch = 512, n_predict = 512, n_keep = 0


 Tell me about the relations between Typhoon Khanun and Jamboree in South Korea.
Tell me about the relations between Typhoon Khanun and Jamboree in South Korea.
Jamboree is a term used to describe a large-scale storm that affects parts of East Asia, including Japan, China, and Korea. Typhoons are intense tropical cyclones that form over warm waters in the Pacific Ocean and move northward along the eastern coast of Asia. The relations between Typhoon Khanun and Jamboree in South Korea can vary depending on several factors, such as the storm's intensity, direction, and timing.
Here are some key points to consider:
1. Impact on agriculture: Typhoons can cause significant damage to crops, particularly those that are sensitive to strong winds and heavy rainfall. This can lead to losses in agricultural productivity and food security, especially if the storm hits during the growing season. Jamboree may have a similar impact on South Korea's agriculture, given its large scale and potential for intense weather conditions.
2. Flooding risks: Typhoons often bring heavy rainfall and storm surges that can lead to flooding in low-lying areas. This can cause damage to homes, infrastructure, and other properties, as well as disrupt transportation and communication systems. Similarly, Jamboree may pose a flooding risk to South Korea, particularly if it makes landfall in an area with poor drainage or inadequate flood protection measures.
3. Power outages: Strong winds and heavy rain associated with Typhoon Khanun could lead to power outages and disrupt electricity supply in the affected areas. Jamboree may also cause similar issues, particularly if it affects transmission lines or electrical infrastructure.
4. Disruption of transportation: Typhoons can severely impact transportation networks, including air, land, and sea routes. This can lead to delays, disruptions, or even cancellations of flights, trains, and buses, as well as logistical challenges in delivering goods and supplies. Similarly, Jamboree may cause disruptions to South Korea's transportation systems, particularly if it affects major highways, airports, or seaports.
5. Economic impact: Typhoons can have a significant economic impact, particularly in areas with heavy industry

llama_print_timings:        load time =   633.88 ms
llama_print_timings:      sample time =   492.98 ms /   512 runs   (    0.96 ms per token,  1038.59 tokens per second)
llama_print_timings: prompt eval time = 38543.69 ms /   277 tokens (  139.15 ms per token,     7.19 tokens per second)
llama_print_timings:        eval time = 91545.65 ms /   510 runs   (  179.50 ms per token,     5.57 tokens per second)
llama_print_timings:       total time = 130660.22 ms

 

 

 

2023 년 현재 태풍 카눈과 잼버리 대회와의 관계에 대해 물어봤는데 일반적인 내용만 정리해 줍니다.

당연히 최근에 진행중인 데이터를 학습하지 않았기 때문입니다.

2) SingleStoreDB 에 데이터 벡터 저장

2023년 태풍 카눈에 대한 내용을 wikipedia 에서 복사하여 텍스트 파일로 만들고 이를 SingleStoreDB 의 Vector Embedding 으로 저장하겠습니다. 파일은 아래에 첨부했습니다.

먼저 Embedding 및 Llama 에 사용할 Python Package 들을 설치합니다.

 

 

$ python -m venv .venv
$ source .venv/bin/activate
$ pip install llama-cpp-python==0.1.77
$ pip install langchain==0.0.236
$ pip install sentence_transformers
$ pip install singlestoredb

 

 

다음 Python 프로그램을 이용하여 Embedding 모델 및 Vector Store 를 각각 all-MiniLM-L6-v2, SingleStoreDB 로 선택합니다.

그 후 khanun.txt 파일을 chunk 단위로 분리한 다음 SingleStoreDB 로 업로드합니다.

 

 

$ python3

import os
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import SingleStoreDB

embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", 
                                   model_kwargs={'device': 'cpu'})
loader = DirectoryLoader('./', glob='khanun.txt', loader_cls=TextLoader)
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50)
texts = text_splitter.split_documents(documents)

os.environ["SINGLESTOREDB_URL"] = "user:pass@127.0.0.1:3306/vectordb"
vectorstore = SingleStoreDB.from_documents(texts, embeddings, distance_strategy="DOT_PRODUCT", 
                                           table_name="demo")
 
 
 

자동으로 demo 라는 테이블이 만들어 졌으며 content 컬럼에 데이터 텍스트, vector 에 embedding, metadata 에 source 파일명이 저장되었습니다.

3) SingleStoreDB 의 Vector 우선 검색 후 LLM 호출

langchain 의 Retrieval QA 를 만들어 Vector Store 를 SingleStoreDB 로 지정하여 질의를 수행하도록 하겠습니다.

qa_template 은 SingleStoreDB 로부터 전달받은 Data Context 를 이용해 사용자의 질의에 정확하고 의미있는 답변을 요청하도록 질문 템플릿이 구성되어 있습니다.

 

 

$ python3

import os
from langchain.embeddings import HuggingFaceEmbeddings
from langchain import PromptTemplate
from langchain.vectorstores import SingleStoreDB
from langchain.llms import LlamaCpp
from langchain.chains import RetrievalQA


embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", 
                                   model_kwargs={'device': 'cpu'})

os.environ["SINGLESTOREDB_URL"] = "user:pass@127.0.0.1:3306/vectordb"
vectorstore = SingleStoreDB(embeddings, distance_strategy="DOT_PRODUCT", table_name="demo")

qa_template = """Use the following pieces of information to answer the user's question.
If you don't know the answer, just say that you don't know, don't try to make up an answer.

Context: {context}
Question: {question}

Only return the helpful answer below and nothing else.
Helpful answer:
"""

prompt = PromptTemplate(template=qa_template, input_variables=['context', 'question'])

 

langchain 의 llm 을 다운로드 받은 모델로 선택하고 이를 이용해 RetrievalQA 를 생성합니다.

이 때 SingleStoreDB 를 retriever 로 지정하고 3개의 KNN 유사도 검색 결과를 사용하도록 설정합니다.

 

llm =  LlamaCpp(model_path="/home/opc/llama.cpp/models/llama-2-7b-chat.ggmlv3.q4_K_S.bin", 
                n_gpu_layers=1, n_batch=512, f16_kv=True, verbose=False)

dbqa = RetrievalQA.from_chain_type(llm=llm,
                                   chain_type='stuff',
                                   retriever=vectorstore.as_retriever(search_kwargs={'k': 3}),
                                   return_source_documents=True,
                                   chain_type_kwargs={'prompt': prompt})

 

이제 다시 태풍 카눈과 잼버리 대회의 관계에 대해 질의해 보겠습니다.

카눈의 변경된 진로 및 예상되는 영향으로 인해 정부와 스카우트 조직이 대회를 빨리 끝냈다고 정확한 대답을 해 줍니다.

 

response = dbqa({'query':'Tell me about the relations between Typhoon Khanun and Jamboree in South Korea'})
print(f'\nAnswer: {response["result"]}')

Answer: Typhoon Khanun affected the 25th World Scout Jamboree, which was held in South Korea. 
The Korean government and the World Organization of the Scout Movement decided to end the jamboree early due to the typhoon's changed path and expected impact

 

한번 더 동일한 질문을 수행할 경우의 결과입니다.

 

Answer: The World Organization of the Scout Movement (WOSM) decided to end the ongoing 25th World Scout Jamboree early
 in cooperation with the Korean government due to the impact of Typhoon Khanun in South Korea.
 

 

마무리

외부에 공개할 수 없거나 LLM 이 학습하지 못한 최신 데이터의 벡터 저장 및 검색을 위해서는 On-Premises 에 SingleStoreDB 를 설치하여 빠른 벡터 연산 및 유사도 검색 기능을 활용할 수 있습니다.

다른 Vector Database 에 비해 SingleStoreDB 는 대용량 실시간 처리, Native Vector 연산, JSON 메타 데이터와의 Join 및 Aggregation 등 벡터 기능 뿐만 아니라 RDBMS 만의 데이터 처리 및 분석 기능을 함께 사용할 수 있어 더욱 활용도가 높습니다.

참고로 예제에서 사용한 모델은 GPU 없이 CPU 만으로도 사용할 수 있도록 양자화된 모델이므로 Linux, Windows, Mac 에서 모두 간단하게 테스트해 볼 수는 있으나 속도가 매우 느립니다.

느린 속도에도 불구하고 On-premises 환경에서 LLM, Embedding 모델, VectorDB 로써의 SingleStoreDB 를 모두 로컬 환경에 구성하고 사용해 보기에는 충분하리라고 생각합니다.

도움이 되시길 바랍니다.

감사합니다.