임베딩

임베딩은 데이터를 벡터화된 형식으로 표현하는 방법으로, 유사한 문서를 쉽고 효율적으로 찾을 수 있도록 합니다.

현재 임베딩은 이슈에만 생성되며 다음과 같은 기능을 제공합니다.

아키텍처

임베딩은 Elasticsearch에 저장되며 고급 검색에도 사용됩니다.

graph LR A[데이터베이스 레코드] --> B[ActiveRecord 콜백] B --> C[임베딩 참조물 빌드] C -->|큐에 추가| N[큐] E[매분 cron 작업] <-->|큐에서 가져오기| N E --> G[참조물 역직렬화] G --> H[임베딩 생성] H <--> I[AI 게이트웨이] I <--> J[정점 API] H --> K[임베딩이 있는 문서 추가/갱신] K --> L[Elasticsearch]

이 프로세스는 Search::Elastic::ProcessEmbeddingBookkeepingService에 의해 주도되며 Redis 큐에 추가하고 가져옵니다.

임베딩 큐에 추가

다음은 이슈를 예시로 한 임베딩 큐에 추가하는 과정 설명입니다.

이슈 임베딩은 "이슈 제목 '#{issue.title}' 및 설명 '#{issue.description}'"의 내용에서 생성됩니다.

Search::Elastic::IssuesSearch에서 정의된 ActiveRecord 콜백을 사용하여 이슈에 대한 임베딩 참조물이 생성되고, 이슈가 생성되거나 제목 또는 설명이 업데이트되었고 임베딩이 생성 가능한 경우에 임베딩 큐에 추가됩니다.

임베딩 큐에서 가져오기

Search::ElasticIndexEmbeddingBulkCronWorker cron 작업이 매분 실행되며 다음을 수행합니다.

graph LR A[cron] --> B{엔드포인트 쓰로틀링됨?} B -->|아니요| C[16개의 워커 예약] C ..->|각 워커| D{엔드포인트 쓰로틀링됨?} D -->|아니요| E[큐에서 19개의 참조물 가져오기] E ..->|각 참조물| F[엔드포인트 증가] F --> G{엔드포인트 쓰로틀링됨?} G -->|아니요| H[AI 게이트웨이 호출하여 임베딩 생성]

그러므로 16개의 동시 프로세스가 동시에 임베딩을 생성하더라도 450개 임베딩/분의 속도 제한 설정을 초과하지 않도록 항상 확인합니다.

백필링

고급 검색 마이그레이션은 백필링을 수행하는 데 사용됩니다. 이는 큐에 참조물을 일괄로 추가한 뒤 앞에서 설명한 cron 작업에 의해 처리됩니다.

새로운 임베딩 유형 추가

다음은 임베딩을 생성하고 Elasticsearch에 저장하기 위한 단계 개요입니다.

  1. Elasticsearch 클러스터가 임베딩 생성을 처리할 수 있는지 또는 추가 리소스가 필요한지 비용 및 리소스 계산을 수행합니다.
  2. 임베딩을 저장할 위치를 결정합니다. 기존 Elasticsearch 인덱스를 확인하고 적합한 기존 인덱스가 없는 경우 새 인덱스를 만듭니다.
  3. 인덱스에 임베딩 필드를 추가합니다: 예시.
  4. 내용을 생성할 수 있도록 방식을 업데이트하여 새로운 유형을 수용합니다.
  5. 새 단위 원시를 추가합니다: 여기여기.
  6. 임베딩을 생성할 시기에 필요한 검사를 추가하기 위해 Elastic::ApplicationVersionedSearch를 사용합니다. 예시는 Search::Elastic::IssuesSearch를 참조하세요.
  7. 임베딩을 백필링합니다: 예시.

로컬에 이슈 임베딩 추가

전제 조건

  1. Elasticsearch가 실행 중인지 확인합니다.
  2. 기존 Elasticsearch 설정이 있는 경우 다음을 실행하여 AddEmbeddingToIssues 마이그레이션이 완료되었는지 확인합니다.

    Elastic::MigrationWorker.new.perform
    
  3. 로컬 환경에서 GitLab Duo 기능을 실행할 수 있는지 확인합니다.
  4. 레일즈 콘솔에서 다음을 실행하여 임베딩(768 차원의 벡터)이 출력되는지 확인합니다. 그렇지 않은 경우 AI 설정에 문제가 있는 것입니다.

    Gitlab::Llm::VertexAi::Embeddings::Text.new('text', user: nil, tracking_context: {}, unit_primitive: 'semantic_search_issue').execute
    

백필링 실행

프로젝트의 이슈에 대한 임베딩을 백필링하려면 레일즈 콘솔에서 다음을 실행합니다.

Gitlab::Duo::Developments::BackfillIssueEmbeddings.execute(project_id: project_id)

이 작업은 이슈를 큐에 추가하고 일괄로 처리하여 Elasticsearch에 임베딩을 색인화합니다. 분당 450개의 임베딩 속도 제한을 준수합니다. 문제가 있는 경우 Slack의 @maddievn 또는 #g_global_search로 문의하십시오.

확인

만약 다음 내용이 0을 반환한다면, 프로젝트의 모든 이슈에는 임베딩(embedding)이 있습니다:

curl "http://localhost:9200/gitlab-development-issues/_count" \
--header "Content-Type: application/json" \
--data '{"query": {"bool": {"filter": [{"term": {"project_id": PROJECT_ID}}], "must_not": [{"exists": {"field": "embedding"}}]}}}' | jq '.count'

PROJECT_ID를 귀하의 프로젝트 ID로 대체하세요.