최근에 LLM을 이용하여 로컬 데이터를 검색하는 서비스를 만드는 프로젝트를 하나 진행했습니다. OpenAI API를 활용해 데이터를 처리하면 되는 간단한 프로젝트였는데요. LLM 액세스 도구는 직접 구축하기 보단 LlamaIndex를 사용했습니다. 그 내용을 간략하게 소개합니다.
LlamaIndex
LlamaIndex는 LLM 애플리케이션을 위한 데이터 프레임워크입니다. 우리가 LLM을 사용하여 무언가 작업을 처리할 때 LLM 모델 자체가 학습한 데이터만으로는 부족한 경우가 많죠. 이럴 땐 커스텀 데이터를 LLM에 추가로 입력하여 처리를 하게 되는데요.
이럴 때 사용하는 방법이 1) 파인튜닝(fine-tuning)과 2) 프롬프트 엔지니어링(prompt engineering) 이죠. OpenAI에서도 최근 GPT-3.5 Turbo 모델에 대한 파인튜닝 서비스를 오픈하긴 했지만, 불과 얼마 전까지만 해도 파인튜닝을 할 수 없어 결국 프롬프트에 의존하는 방법 밖에 없었죠.
이럴 때 커스텀 데이터를 프롬프트에 추가 컨텍스트(context)로 입력하여 LLM 모델 액세스의 결과 품질을 향상시키게 되는데요. LlamaIndex가 바로 이 용도에 맞춘 프레임워크라고 보면 됩니다.
RAG(Retrieval Augmented Generation)
이렇게 프롬프트를 통해 컨텍스트 정보를 추가함으로써 LLM 모델의 결과 품질을 높이는 것을 RAG(Retrieval Augmented Generation)이라고 부르는데요. 우리말로 하면 ‘검색 증강 생성’ 쯤 되려나요?
암튼, RAG은 다음과 같이 크게 2개의 단계로 나뉩니다.
- 인덱싱 스테이지: 지식베이스(Knowledge Base)를 준비하는 단계
- 쿼리 스테이지: 지식베이스로 부터 추출한 컨텍스트(Context)를 활용해 LLM에 질의하는 단계


인덱싱 스테이지(Indexing State)에서는 다음과 같은 작업을 합니다:
- 데이터 소스로부터 데이터를 로드
- 로드한 데이터를 문서(Documents)로 변환
- 변환한 문서에 대한 색인(Index) 생성
- (필요하면) 색인을 외부 저장소에 저장
한편 쿼리 스테이지(Query State)에서는 다음과 같은 작업들을 하게 되죠:
- 생성된 색인으로부터 질의에 맞는 컨텍스트 추출
- 추출한 컨텍스트를 포함하여 LLM 쿼리
- 쿼리 결과의 처리
이에 관한 자세한 내용은 LlamaIndex 문서에 잘 나와 있으니 여기서는 생략하고 그럼 직접 간단하게 LlamaIndex로 데이터 처리 작업을 한번 해 볼까요?
LlamaIndex로 커스텀 데이터 처리
앞서 소개했듯 인덱싱 단계는 커스텀 데이터로부터 LlamaIndex 색인을 생성하는 단계인데요. 기본적인 코드는 다음과 같이 간단합니다.
from llama_index import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader('data').load_data()
index = VectorStoreIndex.from_documents(documents)
위 코드는 data 디렉터리 속에 들어 있는 데이터를 읽어 문서로 만든 다음 해당 문서를 벡터 스토어에 저장하는 것으로 끝납니다. data 디렉터리 속에는 예를 들어 내가 추가하려는 커스텀 데이터를 텍스트 파일 형식으로 추가해 두면 되구요.
여기서는 제가 임의로 다음과 같은 텍스트 데이터를 추가했다고 해 보죠. 최근 뜨거웠던 주제죠. 상온 초전도체에 대한 내용인데요. 인터넷을 검색해서 찾은 내용입니다. OpenAI의 GPT 모델들은 아직까지 이 내용을 학습했을 리 없을테니 아마도 모를 겁니다.
현재까지의 초전도체는 영하 269도부터 영하 183도까지라는 극저온 환경에서 초전도 현상을 보였습니다. 2019년에는 영하 23도, 압력 1700억 Pa에서 초전도 현상을 보이는 란타늄 수소 화합물 만들기도 했습니다. 이때의 환경은 초고압 환경입니다. 1기압이 101325 Pa이니까 상상할 수 없는 높은 압력입니다.
만약 상온 상압에서도 초전도체로 동작하는 물질이 생긴다면 에너지 혁명이 일어날 것입니다. 상온 상압 초전도체를 개발한 사람은 의심할 것 없이 노벨상입니다. 그러므로 2023년 7월에 대한민국에서 상온, 상압의 초전도체를 만들었다는 뉴스는 충분히 세상을 놀라게 할 만합니다. 그 초전도체가 바로 LK-99입니다.
퀀텀에너지 연구소는 논문과 함께 초전도체라고 주장하는 LK-99의 영상을 공개했습니다. 자석 위에 동전 모양의 검은 물체가 비스듬히 들려 있습니다. 완전 공중부양이 아니라 한쪽 면이 자석위에 살짝 닿아있는데요. 어쨌거나 뜨다시피 한 모습은 놀랍습니다. 이 물질이 바로 초전도체 물질이라고 주장하는 LK-99입니다.
2028년 8월 현재 세계의 유명한 대학과 연구소들은 상온 상압 초전도체인 LK-99를 검증하고 있는 중입니다. 예를들어 미국의 프린스턴 대학, 독일의 막스플랑크 연구소는 LK-99가 특이한 성질을 보였지만 초전도체는 아닌듯하다는 결론을 내놓았습니다. LK-99가 초전도체가 아니다라고 단정한 것은 아닙니다. 다만 연구자들을 설득할 만한 충분한 데이터와 설명이 부족하다는 것입니다. 또 다른 과학자들의 검증결과가 기다려집니다.
2023년 7월 LK-99라는 초전도체에 대한 논문이 아카이브에 올라왔고, 그 이후로 초전도체 뉴스가 뜨겁습니다. LK-99라는 초전도체 개발 가능성은 초전도체 활용 분야로 관심이 갔고, 즉시 주식시장에 그 관심이 반영되었습니다.
올해 시장 최대 테마주는 초전도체 관련 주입니다. 초전도체 응용기술을 가졌다는 어떤 기업은 2023년 7월31일부터 상한가 3회로 사흘만에 2배가 올랐습니다. 거래정지 하루가 있었고, 그 다음날엔 하한가를 쳐서 그야말로 주가가 롤러코스터를 타고 있습니다. 주식투자에 각별한 주의가 필요해 보입니다.
확인도 할겸 연습 삼아 OpenAI Playground에서 퀀텀에너지 연구소에 대해 한번 물어 보죠.

결과는 뭐 맞는 거 같기고 하고 환각(hallucination) 같기도 하고 그러네요.
그럼 이번엔 LlamaIndex를 이용해 RAG 쿼리를 한번 수행해 보도록 하겠습니다. 앞에서 처리한 인덱스를 활용하여 다음과 같이 쿼리를 실행합니다.
query_engine = index.as_query_engine()
response = query_engine.query("퀀텀에너지 연구소에 대해 말해줘?")
print(response)
# => 퀀텀에너지 연구소는 2023년 7월에 대한민국에서 상온, 상압의 초전도체를 만들었다는 뉴스를 발표하기 전부터 초전도체 관련 연구를 수행하고 있는 연구소입니다. 그들은 논문과 함께 초전도체라고 주장하는 LK-99의 영상을 공개했습니다. 이 물질이 바로 초전도체라고 주장하는 LK-99입니다. 현재 세계의 유명한 대학과 연구소들은 상온 상압 초전도체인 LK-99를 검증하고 있습니다.
어떤가요? 이번엔 뭔가 제대로 알고 대답하는 것 같죠. 그럴 밖에요. 방금 전 우리가 입력한 데이터를 OpenAI가 받아서 쿼리 결과에 활용했기 때문에 정확한 내용이라고 할 수 있습니다.
이렇게 커스텀 데이터를 활용해 LLM 모델의 정확도를 높이는 게 바로 LlmaIndex에서 RAG의 역할입니다.
RAG의 작동 원리
LlamaIndex에 대한 내용은 여기까지입니다. 하지만 여기서 끝내면 어딘지 조금 밋밋하죠. 그래서 RAG의 내부 구조를 잠깐 살펴보는 시간을 가져볼까 합니다. 관심있는 분만 보세요.
앞서도 살펴봤듯 LlamaIndex는 내부적으로 LLM과 연동하여 동작합니다. LlamaIndex는 여러 LLM 모델을 지원히자만 기본적으로는 OpenAI와 연동하게 되어 있습니다(디폴트 값!).
아래 그림은 LlamaIndex의 워크플로를 표현한 그림인데요.

그림에서 보면 LlamaIndex가 RAG을 처리하는 과정에서 LLM(OpenAI)과 접속하는 부분은 크게 세 부분입니다.
① 색인 생성: 로우 데이터를 입력받아 색인을 만들기 위해 LlamaIndex는 입력 데이터를 토큰 덩어리(chunk) 단위로 잘게 자른 다음 그 토큰 덩어리에 대한 임베딩(embedding) 벡터값을 구해 그 값을 벡터 저장소에 저장합니다. 이 때 임베딩 벡터값을 얻기 위해 OpenAI Embeddings API를 사용합니다. (디폴트 모델=text-embedding-ada-002)
② 쿼리 분석: 벡터 저장소에 저장된 색인을 검색하려면 사용자가 입력한 쿼리 문장을 앞서와 마찬가지로 임베딩 값으로 변환해야 합니다. 이 때도 역시 Embedings API를 사용하게 됩니다.
③ LLM 질의: 마지막으로 색인에서 추출한 컨텍스트를 사용자가 작성한 쿼리에 이어 붙여 LLM에 최종 질의를 합니다. 이 때는 OpenAI Completions API를 엔드포인트로 사용합니다. (디폴트 모델=text-davinci-003)
이 마지막 단계에서 LlamaIndex가 OpenAI에 보내는 프롬프트의 내용은, 앞서 우리가 사용한 질의를 예로 들면, 다음과 같습니다.
Context information is below.
---------------------
현재까지의 초전도체는 영하 269도부터 영하 183도까지라는 극저온 환경에서 초전도 현상을 보였습니다. 2019년에는 영하 23도, 압력 1700억 Pa에서 초전도 현상을 보이는 란타늄 수소 화합물 만들기도 했습니다. 이때의 환경은 초고압 환경입니다. 1기압이 101325 Pa이니까 상상할 수 없는 높은 압력입니다.
만약 상온 상압에서도 초전도체로 동작하는 물질이 생긴다면 에너지 혁명이 일어날 것입니다. 상온 상압 초전도체를 개발한 사람은 의심할 것 없이 노벨상입니다. 그러므로 2023년 7월에 대한민국에서 상온, 상압의 초전도체를 만들었다는 뉴스는 충분히 세상을 놀라게 할 만합니다. 그 초전도체가 바로 LK-99입니다.
퀀텀에너지 연구소는 논문과 함께 초전도체라고 주장하는 LK-99의 영상을 공개했습니다. 자석 위에 동전 모양의 검은 물체가 비스듬히 들려 있습니다. 완전 공중부양이 아니라 한쪽 면이 자석위에 살짝 닿아있는데요. 어쨌거나 뜨다시피 한 모습은 놀랍습니다. 이 물질이 바로 초전도체 물질이라고 주장하는 LK-99입니다.
2028년 8월 현재 세계의 유명한 대학과 연구소들은 상온 상압 초전도체인 LK-99를 검증하고 있는 중입니다. 예를들어 미국의 프린스턴 대학, 독일의 막스플랑크 연구소는 LK-99가 특이한 성질을 보였지만 초전도체는 아닌듯하다는 결론을 내놓았습니다. LK-99가 초전도체가 아니다라고 단정한 것은 아닙니다. 다만 연구자들을 설득할 만한 충분한 데이터와 설명이 부족하다는 것입니다. 또 다른 과학자들의 검증결과가 기다려집니다.
2023년 7월 LK-99라는 초전도체에 대한 논문이 아카이브에 올라왔고, 그 이후로 초전도체 뉴스가 뜨겁습니다. LK-99라는 초전도체 개발 가능성은 초전도체 활용 분야로 관심이 갔고, 즉시 주식시장에 그 관심이 반영되었습니다.
올해 시장 최대 테마주는 초전도체 관련 주입니다. 초전도체 응용기술을 가졌다는 어떤 기업은 2023년 7월31일부터 상한가 3회로 사흘만에 2배가 올랐습니다. 거래정지 하루가 있었고, 그 다음날엔 하한가를
---------------------
Given the context information and not prior knowledge, answer the question: 퀀텀에너지 연구소에 대해 말해줘?
여기서는 입력한 커스텀 데이터의 양이 적어 하나의 전체 데이터가 모두 컨텍스트로 프롬프트에 포함되었지만 실제로는 더 큰 단위의 데이터 중 청크로 나뉜 일부만 컨텍스트로 들어가게 되겠죠. 이게 RAG이고 LlamaIndex가 하는 주된 일입니다.
여기까지 읽어 주셔서 감사합니다! ?
