본문 바로가기

임베딩 기술의 이해: 데이터를 언어로 말하게 하는 벡터의 마법(텍스트, 이미지)

출입금지 발행일 : 2023-11-10

임베딩

임베딩이란?

"임베딩"이란 콘텐츠를 고정된 크기의 부동 소수점 숫자 배열로 변환하는 과정입니다. 이 변환을 통해 콘텐츠의 길이와 상관없이 일정한 크기의 배열을 얻을 수 있으며, 배열의 구체적인 크기는 사용하는 임베딩 모델에 따라 달라집니다(예: 300, 1000, 1536 등). 이 숫자 배열을 가장 잘 이해하는 방법은 그것들을 다차원 공간의 좌표로 생각하는 것입니다.

 

콘텐츠를 다차원 공간에 배치하는 이유는 그 위치를 통해 콘텐츠에 대한 흥미로운 정보를 얻기 위해서입니다. 공간상의 위치는 콘텐츠의 의미론적 의미를 나타내며, 임베딩 모델은 이를 통해 콘텐츠의 색상, 모양, 개념 등 다양한 특성을 포착합니다. 개별 숫자의 정확한 의미를 완전히 이해하는 사람은 없지만, 이러한 위치가 콘텐츠에 관한 유용한 정보를 추출하는 데 도움을 줄 수 있다는 사실은 알려져 있습니다.

 

임베딩을 사용 하여 관련 콘텐츠 찾기

내가 임베딩을 이용하여 해결한 첫 번째 문제는 내 TIL 블로그의 "Related Content" 기능을 만드는 것이었습니다. 이를 위해 OpenAItext-embedding-ada-002 모델을 사용했으며, 이는 API를 통해 사용할 수 있습니다.

 

현재 내 사이트에는 총 472개의 글이 있고, 각 글에 대해서 1536 차원의 임베딩 벡터(부동 소수점 숫자의 배열)를 계산해서, 이 벡터들을 내 사이트의 SQLite DB에 저장했습니다.

 

이제 특정 글에 대한 관련 글을 찾으려면, 해당 글의 임베딩 벡터와 DB 내 다른 글들 간의 코사인 유사성(Cosine Similarity)을 계산한 다음, 거리가 가장 가까운 상위 10개의 일치 항목을 반환하면 됩니다.

def cosine_similarity(a, b):  
    dot_product = sum(x * y for x, y in zip(a, b))  
    magnitude_a = sum(x * x for x in a) ** 0.5  
    magnitude_b = sum(x * x for x in b) ** 0.5  
    return dot_product / (magnitude_a * magnitude_b)

 

OpenAI의 임베딩 API는 매우 저렴하고 사용하기 쉽습니다. 내 TIL 웹사이트에 약 40만 개의 토큰을 임베딩하는 데, 1천 개의 토큰당 $0.0001로 전체 비용은 $0.04에 불과했습니다.

 

API 사용은 간단합니다. API 키를 사용하여 POST 요청을 보내고 텍스트를 전송하면, 부동 소수점 숫자로 이루어진 JSON Array를 반환받습니다. 그러나 이 기능은 독점 모델이며, 몇 달 전 OpenAI는 일부 임베딩 모델의 서비스를 종료하기도 했습니다.

 

이는 만약 해당 모델에 많은 수의 임베딩을 저장했다면, 새로운 모델에 맞게 임베딩을 다시 계산해야 한다는 의미입니다. OpenAI는 새 모델로의 재임베딩 비용은 보상하겠다고 하지만, 독점 모델 사용에는 주의가 필요합니다. 이러한 문제는 강력한 공개 라이센스 모델을 선택함으로써 회피할 수 있습니다.

 

Word2Vec 모델에서 어떻게 동작하는지 톧아보기

Google Research가 약 10년 전에 Word2Vec이라는 초기 임베딩 모델에 대해 설명하는 영향력 있는 논문을 발표했습니다. "Efficient Estimation of Word Representations in Vector Space"라는 제목의 이 논문은 2013년에 발표되어 임베딩에 대한 관심을 촉발시켰습니다.

 

Word2Vec은 단일 단어를 300개의 숫자 목록으로 변환하는 모델로, 이 숫자 목록은 해당 단어의 의미와 관련 단어에 대한 정보를 포착합니다. 예를 들어 "france"라는 단어를 검색하면, 코사인 거리를 기준으로 "french", "belgium", "paris", "germany"와 같은 유사한 단어들을 찾을 수 있습니다.

 

이 모델을 사용하면 단어 벡터 간의 산술 연산을 수행할 수 있습니다. 예를 들어 "germany" 벡터에 "paris"를 더하고 "france"를 빼면, 결과 벡터는 "berlin"에 가장 가까워집니다. 이는 Word2Vec 모델이 국적과 지리에 대한 개념을 이해하고 있음을 보여주며, 산술을 사용하여 세계에 대한 추가적인 사실을 탐색할 수 있음을 의미합니다.

 

Word2Vec은 16억 단어의 콘텐츠로 훈련되었으며, 오늘날 사용하는 임베딩 모델은 훨씬 더 큰 데이터 세트에서 훈련되어 기본 관계에 대한 훨씬 더 풍부한 이해를 제공합니다.

 

임베딩 계산 및 검색하기

나는 LLM이라고 하는 CLI(Command Line Interface) 이자 Python 라이브러리를 개발하고 있습니다. 이는 LLM들과 상호작용하기 위한 CLI로 사용될 수 있으며, OpenAPI와의 연동도 지원합니다.

 

몇 달 전, 이 도구에는 SentenceTransformers 라이브러리를 이용하여 임베딩 모델을 실행하는 기능을 플러그인 형태로 추가했습니다.

사용자는 임베딩 컬렉션을 선택하고, Vibes-based 검색을 통해 유사한 항목을 찾을 수 있습니다.

 

또한, Python 코드베이스에서 Symbol을 찾는 Symbex 도구도 개발 중에 있습니다. 이 도구를 통해 코드의 함수에 대한 임베딩을 계산하고, 이를 기반으로 한 코드 검색 엔진을 구축할 수 있습니다.

 

CLI를 이요한 텍스트와 이미지 임베딩

현재 제가 가장 선호하는 임베딩 모델은 CLIP입니다. OpenAI가 2021년 1월에 출시한 이 모델은 텍스트와 이미지를 모두 임베딩 할 수 있으며, 둘을 동일한 벡터 공간에 포함시킵니다.

 

예를 들어, "dog"라는 단어를 임베딩하면, CLIP 모델 구성에 따라 512차원 공간의 위치를 얻게 됩니다. 만약 개 사진을 임베딩하면, 같은 공간 내에서 위치를 얻게 되는데, 이는 문자열 "dog"의 위치와 거리상으로 가까워집니다.

 

이는 텍스트를 사용하여 관련 이미지를 검색하거나, 이미지를 사용하여 관련 텍스트를 검색할 수 있음을 의미합니다. 예를 들어 해변 사진을 임베딩하면 "beach", "city", "sunshine"과 같은 단어들에 대한 유사도 점수를 얻을 수 있습니다.

 

CLIP로 수도꼭지 찾기

Drew Breunigllm-clip 플러그인을 사용하여 수도꼭지 검색 엔진을 구축했습니다. 그는 2만 장의 수도꼭지 사진을 모아 CLIP 모델을 실행했습니다.

이를 통해 다른 수도꼭지와 비슷한 수도꼭지를 찾을 수 있게 되었으며, 유사하면서도 가격이 저렴한 옵션을 찾는 데에도 도움이 됩니다.

 

RAG로 질답하기

ChatGPT를 사용해 본 많은 사람들이 마지막으로 같은 질문을 합니다: "어떻게 하면 내 노트나 우리 회사의 문서에 대해서 답변하게 만들 수 있을까?" 많은 이들이 이를 위해 막대한 비용을 들여 커스텀 모델을 훈련해야 한다고 생각하지만, 실제로는 그럴 필요가 없습니다.

 

LLM(Large Language Model)RAG(Retrieval Augmented Generation)를 통해 이를 가능하게 할 수 있습니다.

핵심 아이디어는 사용자가 질문을 하고, 당신의 개인적인 문서에서 해당 질문에 관련된 내용을 찾은 후, 그 발췌문을 원래의 질문과 함께 LLM에 입력하는 것입니다. 그러면 LLM은 추가로 제공된 콘텐츠를 기반으로 질문에 답할 수 있게 됩니다. 이 간단한 방법은 놀랍도록 효과적입니다.

 

하지만, 이 기본 버전을 제대로 동작하게 만드는 것은 쉽지 않습니다. 사용자가 물어볼 수 있는 무한한 질문 세트를 고려할 때, 시스템이 가능한 잘 작동하도록 만들어야 합니다. RAG의 주요 문제는 LLM에게 전달할 프롬프트에 포함시킬 콘텐츠의 가장 좋은 발췌문을 파악하는 것입니다.

 

임베딩을 이용한 'Vibes-based' 시맨틱 검색은 사용자의 질문에 답하는 데 필요한 관련성 높은 콘텐츠를 찾는 데 필요한 기능입니다. 제 블로그의 내용에 대한 버전을 구축하여 공개했고, 결과적으로 RAG를 단 한 줄의 Bash 스크립트로 구현할 수 있게 되었습니다.

 

 

반응형

댓글