회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
IT 지식이 무엇보다 중요해진 요즘, 여러분은 어떻게 공부하고 있나요? 가장 먼저 눈길이 가는 건 다양한 IT 강의 영상일 겁니다. 강의를 제공하는 교육 기업들과 함께, 요즘IT에서 ‘IT 강의 시리즈’를 준비했습니다. 엄선한 교육 영상을 텍스트로 읽고 필요한 정보를 빠르게 가져가세요.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
IT 지식이 무엇보다 중요해진 요즘, 여러분은 어떻게 공부하고 있나요? 가장 먼저 눈길이 가는 건 다양한 IT 강의 영상일 겁니다. 강의를 제공하는 교육 기업들과 함께, 요즘IT에서 ‘IT 강의 시리즈’를 준비했습니다. 엄선한 교육 영상을 텍스트로 읽고 필요한 정보를 빠르게 가져가세요.
이번 강의는 ‘랭체인으로 LLM 기반 애플리케이션 설계하기’입니다. 구글 클라우드의 고객 엔지니어이자 이스라엘 라이히만 대학에서 컴퓨터 과학을 가르치는 에덴 마르코(Eden Marco) 님이 강의를 맡았습니다. 랭체인의 기본 개념부터 LLM 애플리케이션 개발에 도움을 주는 도구 정보까지, 텍스트 환경에 적합한 내용들만 간추려 소개합니다. 영어로 진행한 강의의 번역본을 기초로 글을 구성했습니다. 전체 영상은 유데미에서 확인할 수 있습니다.
안녕하세요, 에덴 마르코입니다. 오늘은 LLM의 기본 처리 단위, 토큰 한도 문제를 랭체인으로 처리하는 전략을 다뤄보려고 합니다.
모든 LLM에는 토큰* 한도가 미리 정해져 있죠, 아키텍처에 관계없이요. 보통 한 번의 상호작용에서 처리할 수 있는 토큰의 최대 개수가 있습니다. 대표적으로 GPT 3.5 버전은 토큰 한도를 약 4,000개(4K)로 제한하고 있습니다.
*토큰(Token): LLM이 언어 데이터를 처리하는 기본 단위. 일반적으로 단어, 문자, 또는 문장의 일부를 포함하며, API 사용량 측정의 기준.
시간이 지남에 따라 LLM이 처리할 수 있는 토큰의 수는 계속 증가하고 있습니다. 그러나 LLM의 토큰 수가 계속 증가한다 해도 여전히 제한이 있다는 사실에는 변함이 없습니다. 따라서 해결 방법을 찾아야 해요.
간단히 하기 위해, 토큰 하나를 단어 하나라고 가정해 볼게요. (원래는 그렇지 않습니다. 토큰의 단위는 모델의 토큰화 방식에 따라 달라집니다.)
이때 토큰 개수는 입력 프롬프트와 LLM이 생성하는 응답 모두에서 세어야 합니다. 예시 모델의 토큰 한도가 4,000개라고 할게요. 입력과 응답 모두 합친 단어 수, 즉, 토큰 수가 4,000개를 넘지 않아야 합니다. 그래야 문제없이 작동할 거예요.
한 차례 상호작용 안에서 토큰 개수를 어떻게 나누든 LLM은 상관하지 않습니다. 즉, 프롬프트의 토큰 수는 아주 적게 쓰고, LLM에 응답을 매우 자세하게 써달라고 지시할 수 있죠. 이렇게 하면 대부분의 토큰이 응답 부분에 사용될 겁니다.
또는 반의반으로 나눠 프롬프트를 길게 잡고, 응답은 매우 짧고 간결하게 할 수도 있죠. 토큰 한도를 초과하지 않는 한 LLM은 크게 신경 쓰지 않을 거예요. 잘 소화하고 잘 작동할 겁니다.
그런데 실제 애플리케이션이나 LLM을 고도로 활용하는 경우, 우리는 토큰 한도에 도달하게 됩니다.
원인은 다양한데요. 프롬프트의 컨텍스트가 너무 큰 경우가 많습니다. 이 문제는 (사용자에 달렸기 때문에) 피하기 어렵습니다. 토큰 한도를 초과하면, LLM을 사용할 수 없는 오류가 발생합니다. 단지 토큰을 너무 많이 보내서요.
이러한 토큰 제한을 해결하는 전략이 몇 가지 있습니다. 모두 랭체인에서 지원하는 전략이죠.
스터핑(Stuffing), 맵-리듀스(Map-Reduce), 정제(Refine).
세 가지 전략을 이해하기 가장 좋은 방법은, LLM에 요약(Summarization) 문제를 주는 겁니다.
요약하려는 문서가 많다고 해보겠습니다. 이를 풀기 위해 load_summarize_chain 함수를 쓸 겁니다. 이 함수는 문서를 요약하는 체인을 제공합니다. 이 체인을 초기화할 때, 어떤 체인 유형(chain_type)을 쓸지 인수로 전달할 수 있죠. 여기서 체인 유형을 stuff로 주겠습니다.
이는 요약 체인에 “스터핑 전략으로 컨텍스트를 처리하라”고 명령하는 겁니다.
스터핑이란 무엇일까요? 마치 봉제 인형에 솜이나 섬유를 채워 넣는 것과 같습니다.
랭체인에게 이렇게 말하는 거죠. “프롬프트에 컨텍스트, 즉, 문서를 채우고 싶어.” 라고요. 이 전략에서는 어떤 것도 바꾸지 않고 있는 그대로 전부 프롬프트에 밀어 넣습니다. 이때는 API를 한 번만 호출해도 되죠. 그래서 가장 직관적인 방법입니다.
하지만 우리는 결국 두 개 이상의 문서를 사용할 테고, 토큰 한도에 도달할 겁니다. 문서가 많으면 당연히 토큰도 많아지니까요.
극단적인 경우를 가정해 볼게요. 여기 어떤 크기의 토큰이라도 넣을 수 있는 LLM 모델이 있습니다. 그래도 페이로드(Payload)의 장벽은 여전합니다. 어쨌든 서버에서 해당 요청을 처리해야 하니까요.
이 문제를 해결하는 방법 중 하나는 맵-리듀스 체인을 사용하는 겁니다. 이번에도 load_summarize_chain을 사용하지만, 체인 유형을 map_reduce로 줄 겁니다.
이 체인에서는 프롬프트에 넣을 문서를 모두 LLM으로 직접 전송합니다.
그리고 각 문서별로 새로운 프롬프트를 만듭니다. 이때 프롬프트에는 요약 지침과 컨텍스트가 들어있습니다. 컨텍스트는 문서가 될 겁니다.
Map: 변환하기
‘매핑(mapping)’은 함수형 프로그래밍에서 온 것으로, 어떤 것들의 모음에 변환 함수를 적용하는 방식입니다. 그렇게 매핑을 적용해 새로운 모음을 다시 만듭니다. 컨텍스트가 있는 프롬프트들의 모음이겠죠.
이제 프롬프트를 가져오는 새로운 매핑 단계를 만들게요. 프롬프트는 각각 LLM으로 전송됩니다. 이 변환 과정에서 프롬프트들이 LLM API를 호출하고, 각 문서에 대한 요약을 가져오는 거죠.
이 작업은 전부 병렬로 실행할 수도 있습니다. 성능을 최적화하기에 아주 좋은 장점입니다. 문서가 서로 의존하지 않고 독립적으로 실행될 수 있어 가능한 일입니다.
Reduce: 축소하기
마지막 단계에서는 원본 문서에서 만든 작은 요약들을 가져와 큰 요약을 만듭니다.
미리 만든 요약들을 모아 한 번 더 요약하는 거죠. 전문 용어로 이 작업을 리듀싱(Reducing, 축소)이라고 해요. 요약을 축소하는 함수가 적용됩니다. 즉, LLM을 이터러블(iterable)로 호출하고, 단일 값을 생성하는 거예요. 여기서 말하는 단일 값이 최종 요약이고요.
이 과정을 랭체인에서는 어떻게 구현할까요?
코드 한 줄이면 됩니다. 이 모든 작업을 수행하려면, 체인 유형에 그저 “map_reduce”라고 써주기만 하면 됩니다. 랭체인이 위력을 발휘하는 부분이죠. 랭체인이 우리 대신 이 긴 과정을 모두 처리해 줄 겁니다. 우리가 하지 않아도요.
맵-리듀스의 장점과 한계
맵-리듀스의 장점은 엄청난 수의 문서로 확장할 수 있다는 점입니다. 이 작업을 병렬로 실행할 수 있고요. 그래서 성능 최적화와 빠른 실행에 유리합니다.
하지만 몇 가지 단점도 있죠. 우선 API 호출을 많이 하니 비용에 영향을 미칠 수 있습니다. 또, 각 문서를 요약하는 매핑 과정에서 정보, 즉 컨텍스트가 일부 손실될 수 있고요.
이 문제를 처리하기 위해 정제 체인을 사용합니다.
정제 체인이 하는 일을 가장 잘 이해하려면, 함수형 프로그래밍의 개념 중 하나를 먼저 알아야 합니다.
foldl 함수
함수형 프로그래밍에서, foldl 함수, 정확히 foldLeft 함수는 일반적으로 목록을 반복해 결과를 누적하는 데 사용합니다. 각 요소에 이진 함수를 적용하여 값을 계속 누적하는 거죠. 우리가 앞서 들었던 이항 함수 또는 이항 연산은 이처럼 함수에 인수가 두 개 필요하다는 말을 멋지게 한 것입니다.
foldl 함수는 초깃값과 목록의 첫 번째 요소를 이진 함수에 적용하는 일을 합니다. 그러면 새로운 누적값이 만들어집니다. 이제 새로운 누적값과 두 번째 요소에 이진 함수를 다시 적용합니다. 이 일을 목록의 끝에 도달할 때까지 계속 반복합니다. 그러면 모든 목록을 하나의 값으로 줄이는 거죠.
예를 보겠습니다. foldl, 즉, foldLeft 함수에는 세 개의 매개 변수가 있어요.
첫 번째는 적용할 함수입니다. 두 번째 매개 변수는 초깃값, 세 번째 매개변수는 함수를 적용할 목록입니다.
이렇게 먼저 적용할 함수와 초깃값이 있어야 합니다. 곧 목록에서 첫 번째 요소를 가져와 이 두 인수를 사용하여 함수를 호출합니다. 예시에서 초깃값은 1로, 목록의 첫 번째 요소 1을 가져와 곱할 겁니다. 결과는 1이죠.
목록의 나머지 항목들로도 이 작업을 계속하겠습니다. 목록에서 두 번째 요소인 2를 가져옵니다. 함수를 적용하면, 1에 2를 곱한 결과 2가 나오죠. 이 작업을 계속합니다. 세 번째 요소 3을 곱해 6이라는 값을 얻고, 마지막 요소인 4까지 곱합니다. 이렇게 전체 목록을 24로 줄였습니다. 초깃값과 적용 함수만 사용해서요.
LLM 요약에 적용하기
이번에는 적용 함수가 곱셈 연산자가 아닌, 두 개의 문서를 받아 합치고 요약하는 함수라고 해보죠. 초깃값은 빈 문자열 또는 빈 문서입니다. 목록 매개 변수는 요약하고 싶은 문서의 목록으로 두었습니다.
foldl 함수를 위에서 말한 인수에 적용하면 어떻게 될까요?
먼저 함수가 빈 문서와 첫 번째 문서를 요약할 테고, 그렇게 첫 번째 요약이 나옵니다. 이 첫 번째 요약에 두 번째 문서를 결합해 다시 정제된 상태의 요약을 만듭니다. 이런 식으로 끊임없이 요약을 정제할 겁니다. 모든 문서에 대한 요약이 완벽하게 완성될 때까지요.
정제 체인은 이렇게 구현합니다.
체인 유형에 “refine” 옵션만 입력하면, 랭체인이 모든 백그라운드 작업을 우리 대신 해줄 겁니다. 시간을 많이 절약할 수 있죠.
지금까지 랭체인으로 토큰 한도를 처리하는 3가지 전략을 살펴보았습니다. LLM 요약 문제로 접근해 스터핑, 맵-리듀스, 정체 전략을 알아봤죠.
이러한 전략으로 토큰 한도 문제에 접근하면, 문제를 해결하는 데 큰 도움이 될 겁니다. 복잡한 구현은 랭체인 프레임워크가 해 줄 테니 걱정할 필요 없습니다.
원본 강의 보러 가기 https://bit.ly/udemy_langchain2
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.