사전 임베딩
용어함정

임베딩

gabury1고친 사람 github-actions[bot]

임베딩은 이름 하나로 두 갈래의 일을 가리킵니다. 검색과 머신러닝에서는 글의 뜻을 숫자 목록으로 옮기는 일입니다. 뜻이 비슷한 글은 비슷한 숫자 목록을 얻습니다. 소프트웨어 개발의 다른 분야에서는 한 물건을 다른 물건 안에 넣는 일을 이렇게 부릅니다. 넣는 것에 따라 이 갈래는 다시 세 가지로 나뉩니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 검색 쪽에서 임베딩은 글을 숫자 목록으로 바꾸는 일입니다. 「자동차」와 「차량」은 글자가 달라도 서로 비슷한 숫자 목록이 됩니다. 프로그램·데이터베이스·웹 페이지 쪽에서 들으면 무엇을 다른 것 안에 넣는다는 뜻입니다. 프로그램 안에 스크립트 실행기를 넣고, 회원 데이터 안에 주소 데이터를 넣고, 웹 페이지 안에 다른 사이트의 영상을 넣는 일이 다 여기 듭니다.

왜 이렇게 하나 — 글자를 맞춰 보는 검색은 「차량」으로 「자동차」 글을 못 찾습니다. 뜻을 숫자로 옮겨 두면 숫자끼리 가까운 글을 찾아 뜻으로 검색할 수 있습니다.

어떻게 도나

  1. 학습을 마친 모델에 글을 넣으면 숫자 목록이 나옵니다
  2. 문서마다 숫자 목록을 미리 뽑아 저장해 둡니다
  3. 검색어도 같은 모델로 숫자 목록을 뽑습니다. 그와 가장 가까운 문서를 돌려줍니다

대가 — 에러 코드처럼 글자가 딱 맞아야 하는 검색에는 약합니다. 모델을 바꾸면 저장해 둔 숫자 목록을 전부 다시 뽑아야 합니다.

상세

「임베딩」이 가리키는 일은 네 가지입니다. 가장 자주 만나는 「뜻을 숫자로 옮기는 임베딩」을 길게 봅니다. 나머지 셋은 짧게 짚습니다.

임베딩이 가리키는 네 가지 일

네 뜻을 쓰는 분야 · 넣는 것 · 넣고 난 결과로 나란히 놓으면 아래와 같습니다.

뜻을 숫자로 옮기는 임베딩 실행기를 프로그램에 넣는 임베딩 데이터베이스 레코드에 넣는 임베딩 웹 페이지에 넣는 임베딩
쓰는 분야 검색 · 머신러닝 응용 프로그램 개발 문서 데이터베이스 웹 프런트엔드
넣는 것 글 · 그림 같은 데이터 스크립트를 읽어 실행하는 부품 회원 레코드 안의 주소 같은 데이터 다른 사이트의 그림 · 영상
결과 숫자 목록 하나 스크립트로 기능을 늘리는 프로그램 주소까지 품은 레코드 하나 여러 사이트의 것이 섞인 화면

뒤의 세 칸은 「무엇을 다른 것 안에 넣는다」는 영어 낱말 뜻을 그대로 따릅니다. 첫 칸만 결이 다릅니다. 무엇을 품는 일이 아니라 글을 숫자로 바꾸는 일입니다.

뜻을 숫자로 옮기는 임베딩

벡터는 숫자를 정해진 개수만큼 늘어놓은 목록입니다. [0.9, 0.1, 0.2] 가 숫자 셋짜리 벡터입니다. 숫자 하나하나를 차원이라고 부릅니다. 이 벡터는 3차원입니다.

임베딩은 글이나 그림 같은 데이터를 이런 벡터 하나로 바꾸는 일입니다. 바꿔 나온 벡터도 임베딩이라고 부릅니다. 「임베딩을 뽑는다」는 말과 「임베딩을 저장한다」는 말이 둘 다 쓰입니다.

바꾸는 규칙에는 약속이 하나 있습니다. 뜻이 비슷한 데이터는 서로 가까운 벡터가 됩니다. 「자동차」와 「차량」은 가까운 벡터를 얻습니다. 「바나나」는 둘에게서 먼 벡터를 얻습니다.

글자가 달라도 뜻이 같은 글

글자 일치 검색의 대표가 TF-IDF(Term Frequency-Inverse Document Frequency)와 BM25(Best Matching 25)입니다. 둘 다 검색어와 문서에 같은 낱말이 몇 번 나오는지로 점수를 매깁니다. 그래서 글자가 겹쳐야 점수가 납니다. 「차량 보험」으로 찾으면 「자동차 보험」만 적힌 문서는 「보험」 하나만 겹칩니다.

이 방식에서는 낱말 하나하나가 서로 남남입니다. 「차량」과 「자동차」가 같은 뜻이라는 정보가 어디에도 없습니다. 이 둘을 이어 주려면 동의어 사전을 사람이 따로 만들어 넣어야 합니다.

임베딩은 이 정보를 숫자 안에 담습니다. 「차량」과 「자동차」의 벡터가 가깝게 나오도록 모델이 미리 배워 둡니다. 그러면 글자가 하나도 안 겹쳐도 두 글이 가깝다고 판단할 수 있습니다.

벡터끼리의 가까움

벡터는 원점에서 뻗은 화살표로 볼 수 있습니다. 숫자 셋짜리 벡터는 3차원 공간의 화살표입니다. 두 화살표가 같은 쪽을 가리킬수록 뜻이 가깝다고 봅니다.

이 방향이 얼마나 비슷한지를 재는 값이 코사인 유사도입니다. 두 화살표 사이의 각도로 계산합니다. 같은 쪽을 가리키면 1 에 가깝습니다. 직각으로 벌어지면 0 에 가깝습니다.

임베딩이라는 이름도 이 공간에서 왔습니다. 글 하나를 이 공간 안의 화살표 하나로 들여앉힌다는 뜻입니다.

아래는 설명을 위해 지어낸 3차원 벡터 셋입니다. cosine 은 코사인 유사도를 계산하는 함수입니다. 값은 줄 오른쪽 주석에 적었습니다.

Python
car     = [0.9, 0.1, 0.2]  # 자동차
vehicle = [0.8, 0.2, 0.3]  # 차량
banana  = [0.1, 0.9, 0.1]  # 바나나

cosine(car, vehicle)       # 0.98
cosine(car, banana)        # 0.24

자동차와 차량은 0.98 로 거의 같은 쪽을 가리킵니다. 자동차와 바나나는 0.24 로 많이 벌어져 있습니다. 검색은 이 값이 큰 문서부터 돌려줍니다.

진짜 임베딩은 차원이 수백에서 수천 개입니다. 차원 하나하나에 「탈것」 같은 이름이 붙어 있지도 않습니다. 모델이 학습하면서 스스로 정한 축이라 사람이 읽을 수 있는 뜻이 없습니다.

임베딩을 만드는 모델

글을 벡터로 바꾸는 규칙은 사람이 짜지 않습니다. 머신러닝 모델이 많은 글을 읽고 배웁니다. 이렇게 학습을 마친 모델을 임베딩 모델이라고 부릅니다.

모델이 배우는 단서는 「비슷한 맥락에 나오는 낱말은 뜻도 비슷하다」는 생각입니다. 이 생각을 분포 가설이라고 부릅니다. 「차량」과 「자동차」는 「운전」·「주차」·「보험」 같은 낱말 곁에 자주 나옵니다. 그래서 둘은 가까운 벡터를 얻습니다.

초기의 Word2Vec 같은 방법은 낱말 하나에 벡터 하나를 줬습니다. 그래서 뜻이 여럿인 낱말도 벡터는 하나뿐이었습니다. 먹는 「배」와 타는 「배」가 같은 벡터를 얻었습니다.

요즘 모델은 낱말 앞뒤의 문장까지 보고 벡터를 정합니다. 그래서 같은 「배」도 문장마다 다른 벡터가 나옵니다. 이렇게 문장 전체를 읽고 벡터 하나로 묶은 것이 문장 임베딩입니다. 검색에는 주로 이 벡터를 씁니다.

언어 모델 안의 임베딩

앞 절의 임베딩 모델 안에는 「임베딩」이라는 이름을 단 부품이 하나 더 있습니다. 글을 받아 다음 글을 이어 쓰는 언어 모델에도 같은 부품이 있습니다. 이 부품을 알아 두면 두 「임베딩」을 헷갈리지 않습니다.

모델은 글을 통째로 받지 않습니다. 먼저 토큰이라는 조각으로 쪼갭니다. 조각마다 번호가 붙어 있습니다.

모델의 첫 단계는 이 번호를 벡터로 바꾸는 일입니다. 번호마다 벡터 하나를 적어 둔 표를 찾아봅니다. 이 표가 임베딩 층입니다.

표에 적힌 값은 처음에 아무렇게나 채워집니다. 모델이 학습하는 동안 다른 부분과 함께 조금씩 고쳐집니다. 학습이 끝나면 비슷하게 쓰이는 토큰끼리 가까운 벡터를 갖게 됩니다.

임베딩 층은 토큰 하나를 벡터 하나로 바꾸는 모델 안의 부품입니다. 검색에 쓰는 문장 임베딩은 글 전체가 모델을 끝까지 지나서 나온 벡터입니다. 임베딩 층의 벡터는 그 길의 출발점일 뿐입니다.

임베딩으로 글을 찾는 흐름

임베딩으로 뜻이 가까운 글을 찾는 일을 벡터 검색이라고 부릅니다. 일은 두 단계로 나뉩니다. 문서를 미리 벡터로 바꿔 두는 단계와 검색어가 들어올 때 찾는 단계입니다.

미리 뽑은 문서 벡터는 벡터 데이터베이스에 넣어 둡니다. 벡터 데이터베이스는 벡터를 저장해 두는 저장소입니다. 주어진 벡터와 가까운 것을 빨리 찾아 줍니다.

flowchart TD
    subgraph S1["미리 해 두는 일"]
        D["문서 · 자동차 보험 안내"] --> M1["임베딩 모델"] --> V1["문서 벡터"] --> DB["벡터 데이터베이스"]
    end
    subgraph S2["찾을 때"]
        Q["검색어 · 차량 보험"] --> M2["같은 임베딩 모델"] --> V2["검색어 벡터"]
    end
    V2 --> N["가장 가까운 문서 벡터 찾기"]
    DB --> N
    N --> R["자동차 보험 안내를 돌려준다"]

그림에서 문서와 검색어는 글자가 「보험」 하나만 겹칩니다. 그래도 같은 임베딩 모델을 지나 가까운 벡터가 됩니다. 그래서 벡터 데이터베이스가 이 문서를 찾아냅니다.

문서가 수백만 개면 검색어 벡터를 문서 벡터 전부와 하나씩 대 보는 데 오래 걸립니다. 그래서 가장 가까운 것을 가끔 놓치는 대신 훨씬 빨리 찾는 방법을 씁니다. 이 방법을 근사 최근접 이웃 탐색이라고 부릅니다.

뜻을 숫자로 옮기는 임베딩의 대가

첫째 대가는 글자가 딱 맞아야 하는 검색에 약하다는 것입니다. 에러 코드나 상품 모델명은 한 글자만 달라도 다른 물건입니다. 임베딩은 이런 값을 비슷한 모양의 다른 값과 가깝게 놓기도 합니다.

그래서 글자 일치 점수와 임베딩 점수를 섞어 쓰는 일이 흔합니다. 이 방식을 하이브리드 검색이라고 부릅니다. BM25 가 글자가 맞는 문서를 챙깁니다. 임베딩은 뜻이 맞는 문서를 챙깁니다.

둘째 대가는 벡터가 모델에 묶인다는 것입니다. 다른 모델이 뽑은 벡터끼리는 가까움을 잴 수 없습니다. 모델을 바꾸면 저장해 둔 문서 벡터를 전부 새 모델로 다시 뽑아야 합니다.

셋째 대가는 저장 공간입니다. 차원이 1,000 이고 숫자 하나를 4바이트로 적으면 문서 하나에 4,000 바이트가 듭니다. 문서가 백만 개면 벡터만으로 4기가바이트가 됩니다.

넷째 대가는 왜 그 문서가 걸렸는지 설명하기 어렵다는 것입니다. BM25 는 「이 낱말이 몇 번 겹쳤다」고 댈 수 있습니다. 임베딩은 「벡터가 가까웠다」까지만 말합니다.

인터프리터를 프로그램 안에 넣는 임베딩

여기부터는 「안에 넣는다」는 뜻입니다. 인터프리터는 스크립트를 한 줄씩 읽어 바로 실행하는 프로그램입니다. 이 인터프리터를 다른 응용 프로그램 안에 부품으로 넣는 일을 임베딩이라고 부릅니다.

넣은 쪽 프로그램을 호스트라고 부릅니다. 호스트는 자기 안에서 인터프리터를 띄웁니다. 그리고 사용자가 쓴 스크립트를 넘겨 실행합니다. 사용자는 호스트를 다시 빌드하지 않고도 스크립트로 기능을 늘릴 수 있습니다.

Redis는 Lua 인터프리터를 안에 넣어 두었습니다. 그래서 여러 명령을 묶은 Lua 스크립트를 서버 안에서 한 번에 돌릴 수 있습니다. 3차원 그래픽 프로그램 Blender는 파이썬을 넣어 두었습니다. 메뉴와 도구를 파이썬 스크립트로 늘릴 수 있습니다.

이 임베딩과 방향이 반대인 것이 확장 모듈입니다. 확장 모듈은 파이썬 프로그램이 C 로 짠 모듈을 불러 쓰는 것입니다. 임베딩은 C 로 짠 프로그램이 파이썬을 불러 씁니다. 누가 누구를 품는지가 다릅니다.

flowchart TD
    subgraph E1["확장 모듈"]
        P1["파이썬 프로그램"] -->|불러 쓴다| C1["C 로 짠 모듈"]
    end
    subgraph E2["임베딩"]
        C2["C 로 짠 호스트 프로그램"] -->|안에 띄운다| P2["파이썬 인터프리터"]
        P2 -->|실행한다| S2["사용자가 쓴 스크립트"]
    end

대가는 둘입니다. 호스트와 인터프리터가 한 프로세스 안에서 돕니다. 그래서 스크립트가 오래 걸리면 호스트도 함께 멈춥니다. 또 두 언어 사이에서 값을 넘길 때마다 호스트 쪽 값과 스크립트 쪽 값을 서로 바꿔 줘야 합니다.

문서 안에 문서를 넣는 임베딩

문서 데이터베이스는 데이터를 표 대신 문서 단위로 저장합니다. 여기서 문서는 데이터베이스의 레코드 하나를 뜻합니다. 문서 하나는 필드 이름과 값을 짝지어 적은 덩어리입니다. 값 칸에 다른 문서를 통째로 넣을 수도 있습니다.

함께 읽는 데이터를 한 문서 안에 넣는 일을 이 분야에서 임베딩이라고 부릅니다. 아래는 회원 문서 안에 주소 문서를 넣은 모습입니다.

JSON
{
  "name": "김유미",
  "address": {
    "city": "서울",
    "street": "한강로 1"
  }
}

address 칸의 값이 또 하나의 문서입니다. 회원을 읽으면 주소가 따라옵니다. 관계형 데이터베이스라면 주소 표를 따로 두고 조인으로 붙였을 데이터입니다.

반대편에 서는 방식은 참조입니다. 주문처럼 끝없이 쌓이는 데이터를 회원 문서 안에 넣으면 문서가 한없이 커집니다. 그럴 때는 주문을 따로 저장하고 회원 문서에는 주문의 식별자만 적어 둡니다.

넣으면 한 번 읽어 다 가져옵니다. 대신 같은 데이터가 여러 문서에 복사되면 고칠 때 전부 찾아 고쳐야 합니다.

웹 페이지에 다른 자원을 넣는 임베딩

웹 페이지는 다른 사이트의 그림이나 영상이나 지도를 제 화면 안에 끼워 보여 줄 수 있습니다. <img> · <iframe> · <script> 태그가 이 일을 합니다. 영상 사이트의 「퍼가기」 코드는 대개 <iframe> 태그 한 줄입니다.

브라우저는 다른 출처의 자원을 끼워 보여 주는 것은 대체로 허락합니다. 대신 페이지의 스크립트가 그 자원의 내용을 읽어 가는 것은 대체로 막습니다. 이 규칙이 동일 출처 정책입니다. 끼워 넣기는 됩니다. 들여다보기는 안 됩니다.

어느 뜻인지 가르는 단서

「임베딩」이 나오면 옆에 붙은 낱말을 봅니다. 대개 그것만으로 어느 뜻인지 갈립니다.

함께 나오는 말 뜻
벡터 · 차원 · 모델 · 유사도 · 벡터 검색 뜻을 숫자로 옮긴다
인터프리터 · 호스트 · 스크립트 · 확장 모듈 인터프리터를 프로그램 안에 넣는다
문서 데이터베이스 · 필드 · 참조 · 조인 문서 안에 문서를 넣는다
태그 · 퍼가기 · 다른 출처 웹 페이지에 다른 자원을 넣는다

「임베디드」는 네 가지 임베딩 어느 것과도 다른 말입니다. 장치 안에 들어가 한 가지 일만 하는 컴퓨터를 가리킬 때 씁니다.

관련 항목

임베딩 벡터로 뜻이 가까운 글을 찾는 검색 방식

벡터 검색 · 시맨틱 검색 · 하이브리드 검색 · 재순위화 · 상호 순위 융합 · 검색 증강 생성

임베딩과 맞세워지는 글자 일치 검색

TF-IDF · BM25 · 벡터 공간 모델 · 역색인 · 전문 검색 · 동의어 사전

두 임베딩의 가까움을 재는 척도

코사인 유사도 · 내적 · 유클리드 거리 · 벡터 · 차원

임베딩 벡터를 저장하고 찾는 도구와 알고리즘

벡터 데이터베이스 · 최근접 이웃 · 근사 최근접 이웃 · HNSW · pgvector

임베딩을 만드는 모델과 학습 개념

머신러닝 · 신경망 · 언어 모델 · 트랜스포머 · Word2Vec · 분포 가설 · 임베딩 층 · 토큰화 · 토큰

인터프리터를 넣는 임베딩을 이루는 부품과 언어

인터프리터 · 확장 모듈 · 래퍼 함수 · API · Lua · Python · Redis

문서 임베딩과 맞세워지는 데이터 배치 방식

문서 데이터베이스 · MongoDB · 참조 · 조인 · 정규화 · 비정규화

웹 페이지 임베딩을 다스리는 브라우저 규칙

동일 출처 정책 · CORS · 콘텐츠 보안 정책 · 크로스 사이트 요청 위조 · iframe

임베딩과 이름만 겹치는 다른 용어

임베디드 · 임베디드 데이터베이스 · 색 프로파일 임베딩 · 폰트 임베딩

다른 이름: embedding · embed · 임베드 · 벡터 임베딩 · 임베딩 벡터