Kernel Memory 3. Memory service

https://microsoft.github.io/kernel-memory/service

LLM이 훈련 이후에 만들어진 데이터나 조직 내부 데이터는 모른다는 한계를 극복하기 위한 방법으로 RAG가 제시되었고, 조직 내부 데이터를 관리하기 위해 커널 메모리가 등장습니다. 커널 메모리는 검색 엔진과 함께 RAG를 가능하게 하는 쌍두마차라 할 수 있습니다.

커널 메모리는 애플리케이션에 임베딩 되기 보다는 독립된 서버 서비스로 실행 되는 게 적합합니다.

그래야 여러 대의 서버에 분산되어 클라이언트 애플리케이션을 차단하지 않고 긴 데이터 수집 과정을 실행할 수 있습니다. 또한 서비스만이 AI 모델, 저장소 및 기타 의존성에 접근하기 위한 자격 증명이 필요하므로, 클라이언트 앱을 통해 비밀이 노출되지 않습니다.

커널 메모리는 크게 두 가지 기능 – 저장과 검색 – 을 합니다.

저장

클라이언트가 파일을 보내면, 서비스는 Azure Blobs나 Local Disk 같은 Content Storage에 데이터를 저장합니다 .
이 단계에서 클라이언트는 연결을 유지하며 데이터를 전송하고 저장을 기다립니다. 이 작업이 완료될 때,
커널 메모리는 클라이언트 요청을 릴리즈하고 비동기 파이프라인을 시작합니다.

커널 메모리는 다양한 형식의 파일들이나 웹 페이지에서 텍스트를 추출합니다. 추출 된 텍스트는 파티션으로 분할됩니다. 파티션 별 텍스트를 임베딩하고, 메타데이터와 함께 메모리 DB에 저장합니다.

각 단계 처리를 핸들러라고 합니다. 저장을 처리하기 위해서는 여러 단계들이 필요하기 때문에 핸들러들 여럿으로 파이프라인을 구성합니다. 단계들은 Handlers로 구현되고 Core 라이브러리로 제공됩니다.

커널 메모리는 단계들로 순차적으로 구성된 기본 파이프라인을 제공합니다. 파이프라인 단계는 이전 단계들이 성공적으로 완료 된 후 시작됩니다. 단계 목록과 핸들러 기본 세트는 함께 작동하도록 설계되었습니다. 기본 핸들러를 제거하려면, 대체할 것을 제공해야 합니다.

파이프라인이 완료될 때만 성공적으로 데이터를 가져온 것으로 간주하는데, 이 과정은 일반적으로 몇 초밖에 걸리지 않습니다. 다음과 같은 경우에는 시간이 상당히 길어질 수 있습니다.

단계 1에서: 업로드된 파일이 외부 서비스를 필요로 하는 경우 (예: 큰 PDF 문서에 대한 OCR).
단계 3에서: 사용된 LLM이 요청을 제한하여 초당 몇 개의 벡터만 생성하는 경우.

커널 메모리는 두 storage solutions를 사용합니다.

– 콘텐츠 저장소 Content Storage: 클라이언트에 의해 업로드된 원시 데이터, 파이프라인 상태, 문서에 할당된 고유 ID가 저장됩니다.
– 메모리 저장소 Memory Storage: 검색 기능이 있는 데이터베이스로, 메모리 레코드를 저장합니다.

저장 파이프라인은 documents를 대상으로 합니다. 하나의 document는 하나 이상의 파일들의 컬렉션입니다. 웹 페이지 가져올 때, 시스템은 웹 페이지 Url을 포함된 파일을 포함하는 document를 만듭니다. raw text를 가져올 때도 텍스트 파일을 포함하는 document를 만듭니다.

각 document가 업로드될 때, ingestion handlers는 한 번에 하나씩 호출됩니다. 문서들이 paralled하게 업로드될 수 있습니다. 하지만 한 문서에 대한 ingestion 파이프라인 스템들은 이전 단계가 성공적으로 완료될 때까지 기다립니다.

다음은 코어 라이브러리에 포함된 기본 핸들러 목록입니다:
TextExtractionHandler: 이 핸들러는 일반적으로 처음 호출되며, 파일에서 텍스트를 추출합니다.

클라이언트가 URL을 제공하면, 핸들러는 웹 페이지를 다운로드하고 텍스트를 추출합니다. 이 핸들러의 출력은 Content Storage에 저장되어 다음 핸들러에 의해 추가 처리됩니다.

이 핸들러는 OCR 및 콘텐츠 유형 감지를 담당합니다.

TextPartitioningHandler: 이 핸들러는 텍스트를 작은 조각으로 나누는 간단한 작업을 다룹니다. 핸들러는 이전 핸들러가 생성한 텍스트 파일을 찾아 일반 텍스트와 마크다운을 약간 다르게 관리합니다.

기본 핸들러는 코드 구문, 채팅 로그, JSON 또는 기타 구조화된 데이터를 이해하지 못하며, 항상 문자열로 처리됩니다. 특정 형식을 다루는 경우, 사용자 입력을 더 잘 분할하기 위해 이 핸들러를 맞춤형 복사본으로 교체하고 싶을 수 있습니다.

기본 핸들러는 텍스트를 문장(또는 “줄”이라고도 함)으로 나누고, 이를 단락(또는 “파티션”이라고도 함)으로 집계합니다. 줄/문장/단락/파티션의 크기는 토큰으로 측정됩니다.

설정할 수 있지만 사용하는 임베딩 생성기에 따라 달라질 수 있습니다: 파티션이 너무 크면 일부 임베딩 생성기는 임베딩 벡터를 생성하라는 요청에 오류를 발생시킬 수 있으며, 일부 임베딩 생성기는 초과 토큰을 무시하여 불완전한 메모리 레코드를 생성할 수 있습니다.

이 핸들러는 모든 작업이 로컬에서 메모리 내에서 이루어지기 때문에 일반적으로 매우 빠릅니다. 파티션이 준비되면 같은 Content Storage에 저장되어 다음 단계를 위해 준비됩니다.

현재 파티션 파일은 원시 텍스트 파일로 저장됩니다.

GenerateEmbeddingsHandler: 이 핸들러는 각 파티션 파일을 로드하고, 텍스트를 가져와 설정된 임베딩 생성기에 임베딩 벡터 계산을 요청합니다.

벡터는 JSON으로 직렬화되어 Content Storage에 다시 저장됩니다. 이 핸들러는 한 번에 하나의 파티션을 처리하며, 병렬 처리 없이 진행되며, 사용된 LLM에 따라 몇 밀리초에서 몇 분이 걸릴 수 있습니다. 이는 또 다른 핸들러로, 임베딩 생성기에 최적화된 것으로 교체할 수 있습니다. 예를 들어, 여러 요청을 병렬로 보내거나 캐시를 사용하는 등의 방법이 있습니다.

SaveRecordsHandler: 이 핸들러는 이전 핸들러가 생성한 임베딩을 하나 이상의 메모리 DB에 저장합니다.

이 작업에는 출처, 파티션 텍스트, 태그 및 검색에 유용한 기타 메타데이터가 포함됩니다.

이 작업은 일반적으로 매우 빠르며, 제공된 문서 ID가 이전에 업로드된 문서와 일치하는 경우 기존 레코드를 업데이트합니다.

DeleteIndexHandler: 이 핸들러는 클라이언트가 문서를 삭제하도록 요청할 때 사용하는 핸들러입니다. 핸들러는 이 문서에서 추출된 모든 메모리를 순환하며 메모리 레코드와 파일을 삭제합니다.

DeleteGeneratedFilesHandler: 이 핸들러는 내용 저장소에 파일 사본을 보관하고 싶지 않은 경우에 사용되는 선택적 핸들러입니다. SaveRecordsHandler 이후에만 호출해야 합니다.

SummarizationHandler: 이 핸들러는 클라이언트가 파일 업로드의 요약을 생성하고 저장하도록 요청할 수 있는 선택적 핸들러입니다. 요약은 시간이 많이 걸릴 수 있으므로 SaveRecordsHandler 이후에 실행하는 것이 좋으며, 요약을 포함하도록 TextPartitioningHandler와 GenerateEmbeddingsHandler를 반복합니다.

문서를 업로드할 때 특별히 지정하지 않는 한, 커널 메모리는 기본적으로 다음 단계로 구성된 파이프라인을 시작합니다.

  1. “extract”
  2. “partition”
  3. “gen_embeddings”
  4. “save_records”

기본 단계 목록은 설정 파일의 KernelMemory.DataIngestion.DefaultSteps에 작성합니다. 요약과 같은 추가적인 처리가 요구되지 않는 다면, 기본 단계를 변경 할 일은 없을 것 같습니다.

About the Author
(주)뉴테크프라임 대표 김현남입니다. 저에 대해 좀 더 알기를 원하시는 분은 아래 링크를 참조하세요. http://www.umlcert.com/kimhn/

Leave a Reply

*