

안녕하세요. 오늘 정리할 내용은 캐싱과 직렬화입니다.
우선 캐싱에 대해서 알아보도록 하겠습니다.
우선 캐싱(Caching)이란 어떤 요청에 대한 답변을 기록해 두었다가 다음번에 같은 요청이 들어오면 기록한 답변을 바로 제공해줌으로써 자원과 비용을 아끼는 행위로 볼 수 있겠습니다.
이러한 의미로서 LangChain은 LLM을 위한 선택적 캐싱 레이어를 제공하는데요
1.동일한 완료를 여러번 요청하는 경우 LLM 공급자에 대한 API 호출 횟수를 줄여 비용을 절감할 수 있습니다.
2.LLM 제공 업체에 대한 API호출 횟수를 줄여 애플리케이션의 속도를 높일 수 있습니다.
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
# 모델을 생성합니다.
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
# 프롬프트를 생성합니다.
prompt = PromptTemplate.from_template("{country} 에 대해서 200자 내외로 요약해줘")
# 체인을 생성합니다.
chain = prompt | llm
와 같이 일반적으로 랭체인을 통해 Chatgpt 모델에 쿼리하는 코드가 있다고 가정합니다.
%%time
response = chain.invoke({"country": "한국"})
print(response.content)
그럼 다음과 같은 응답을 얻을 것입니다.
한국은 동아시아에 위치한 고도로 발전한 산업화된 나라이며, 서울을 중심으로 현대화가 빠르게 진행되고 있습니다. 전통문화와 현대문화가 조화롭게 어우러진 나라로, 한류 문화를 세계에 알리며 글로벌 명품 브랜드들을 배출하고 있습니다. 또한 한반도에 위치해 북한과의 관계가 중요한 이슈로 계속해서 주목받고 있는 나라이기도 합니다. 한국은 높은 교육 수준과 현대적인 인프라를 보유하고 있어 외국인들에게 인기 있는 여행지이기도 하며, 맛있는 음식과 아름다운 자연경관도 많이 갖추고 있습니다. 혁신적인 기술력과 창의성으로 세계를 놀라게 하는 한국은 빠르게 성장하고 변화하는 나라입니다.
CPU times: total: 62.5 ms
Wall time: 2.47 s
그럼 이제 캐시를 적용해 볼까요?
%%time
from langchain.globals import set_llm_cache
from langchain.cache import InMemoryCache
# 인메모리 캐시를 사용합니다.
set_llm_cache(InMemoryCache())
# 체인을 실행합니다.
response = chain.invoke({"country": "한국"})
print(response.content)
다음과 같은 코드를 보시면 set_llm_cache와 ImMemoryCache를 import한 것을 보실 수 있습니다.
그리고
set_llm_cache(InMemoryCache())
를 통해 인메모리 캐시를 사용하도록 사용하게 한 것을 보실 수 있습니다.
그리고 체인을 생성하고 invoke하고 나서 답변을 보니
한국은 동아시아에 위치한 나라로, 서울이 수도이다. 5000년의 역사를 자랑하는 한국은 독특한 문화와 전통을 가지고 있다. 불교, 기독교, 천주교 등 다양한 종교가 있으며, 한글이라는 고유의 문자를 사용한다. 대한민국은 대다수가 한국인이지만 소수민족인 중국계, 일본계, 외국인 등 다양한 인종이 살고 있다. 한국은 세계에서 선진국 중 하나로 인식되며, K-pop, K-drama 등 한류 문화가 세계적으로 인기를 끌고 있다. 또한 삼성, 현대자동차, LG전자 등의 기업이 세계적인 기업으로 성장하며 경제적으로도 중요한 역할을 한다. 한반도 북한과의 관계가 여전히 긴장 상태에 있지만, 향후 통일을 향한 노력이 진행되고 있다.
CPU times: total: 0 ns
Wall time: 3.84 ms
사실상 있던 거 그냥 끌어다 쓰는 수준으로 빠릅니다.
사실 핵심은 있던 거를 끌어다 쓰는 게 맞습니다.
이러한 인메모리 캐시는 휘발성입니다. 프로그램이 실행 중에만 캐시가 보존되는 데요 따라서 웹서비스와 같이 사용자 별로 캐시를 관리해야 하는 경우 유용합니다.
다음으로는 SQLite Cache가 있는데요.
from langchain_community.cache import SQLiteCache
from langchain_core.globals import set_llm_cache
import os
# 캐시 디렉토리를 생성합니다.
if not os.path.exists("cache"):
os.makedirs("cache")
# SQLiteCache를 사용합니다.
set_llm_cache(SQLiteCache(database_path="cache/llm_cache.db"))
다음과 같이 사용할 수 있습니다.
SQLiteCache를 import 한 것을 보실 수 있는데요.
코드를 해석해보면, 우선 캐시를 저장하기 위한 디렉터리를 생성하고 그 디렉터리에 llm_cache.db라는 db를 저장한 모습입니다. 따라서 일종의 Lite한 DB를 써서 영속적인 캐싱을 가능하게 해줍니다.
%%time
# 체인을 실행합니다.
response = chain.invoke({"country": "한국"})
print(response.content)
따라서 다음과 같이 쿼리 했을 경우
한국은 동아시아에 위치한 나라로, 서울이 수도이다. 5000년의 역사를 자랑하는 한국은 독특한 문화와 전통을 가지고 있다. 불교, 기독교, 천주교 등 다양한 종교가 있으며, 한글이라는 고유의 문자를 사용한다. 대한민국은 대다수가 한국인이지만 소수민족인 중국계, 일본계, 외국인 등 다양한 인종이 살고 있다. 한국은 세계에서 선진국 중 하나로 인식되며, K-pop, K-drama 등 한류 문화가 세계적으로 인기를 끌고 있다. 또한 삼성, 현대자동차, LG전자 등의 기업이 세계적인 기업으로 성장하며 경제적으로도 중요한 역할을 한다. 한반도 북한과의 관계가 여전히 긴장 상태에 있지만, 향후 통일을 향한 노력이 진행되고 있다.
CPU times: total: 0 ns
Wall time: 4.89 ms
마찬가지로 그냥 답변해 놓았던 거 끌어다 씁니다.
따라서 다음과 같이 캐싱을 사용하여 비용을 절감할 수 있음을 알았습니다.
이전에 제가 만든 프로그램에 적용했었더라면 좋았겠네요.
이제 직렬화에 대해서 설명하겠습니다.
직렬화(serialization)이란
정의: 모델을 저장 가능한 형식으로 변환하는 과정
목적:
- 모델 재사용(재훈련 없이)
- 모델 배포 및 공유 용이
- 계산 리소스 절약
목적:
- 빠른 모델 로딩
- 버전 관리 가능
- 다양한 환경에서 사용 가능