7장. 자체 임베딩과 벡터DB, 검색 품질
오픈소스 LLM 비교와 선택
자동차를 살 때 연비, 힘, 크기, 값을 표로 놓고 견줍니다. 광고 문구보다 우리 가족이 실제로 타는 길에서 시승해 보는 것이 가장 정확합니다. RAG 에 붙일 LLM 도 우리 문서와 질문으로 직접 시험해 고릅니다.
네 카드가 LLM 을 고르는 기준입니다. 우리 질문에 얼마나 맞게 답하는지(근거 조항 표시와 모를 때의 답 포함), 한 번 답하는 데 얼마나 걸리는지, GPU 메모리에 들어가는지, 회사에서 써도 되는 라이선스인지 봅니다. 여기서 시승이 우리 질문 묶음으로 하는 채점입니다.
이 PC 에서 견줄 모델
모두 Ollama 로 내려받아 씁니다. 4GB GPU 에 들어가는 3B 이하의 작은 모델들입니다.
| 모델 | 만든 곳 | 파일 크기 | 라이선스 |
|---|---|---|---|
qwen2.5:1.5b | Alibaba(Qwen) | 986MB | Apache 2.0 |
qwen2.5:3b | Alibaba(Qwen) | 1.9GB | Qwen Research 라이선스 |
gemma3:1b | 806MB | Gemma 이용 약관 | |
llama3.2:1b | Meta | 1.3GB | Llama 3.2 커뮤니티 라이선스 |
라이선스마다 상업적 사용, 사용자 수, 금지하는 쓰임 같은 조건이 다릅니다. 회사에서 쓰기 전에는 원문을 읽고 담당 부서에 확인합니다.
비교표의 꼴
프로젝트에서는 모델마다 같은 질문 25개를 묻고 이런 표를 만듭니다.
import pandas as pd
# 표의 꼴만 보이는 빈 표. 숫자는 프로젝트에서 채운다
cols = ["모델", "정답(/20)", "출처 맞음(/20)", "지나친 거절", "모름 맞음(/5)", "25문항 초", "라이선스"]
table = pd.DataFrame(columns=cols)
print(table.columns.tolist())정답과 출처는 규정에 있는 질문 20개로, 모름 맞음은 없는 질문 5개로 셉니다. 숫자 하나로 순위를 매기지 않고, 우리 서비스에 무엇이 중요한지(틀린 답이 더 위험한지, 느린 것이 더 문제인지)에 따라 고릅니다.
코드에 나오는 함수
| 코드 | 쉬운 뜻 |
|---|---|
cols = [...] | 비교표의 칸 이름 일곱 개다. 칸 이름의 (/20) 은 "20문항 가운데 몇 개"라는 뜻이다 |
pd.DataFrame(columns=cols) | 칸 이름만 있고 줄은 하나도 없는 빈 표를 만든다 |
table.columns.tolist() | 표의 칸 이름을 파이썬 목록으로 꺼낸다 |
이 코드가 뜻하는 것
자동차 시승 전에 "연비, 힘, 값" 칸만 그어 둔 빈 비교표를 준비하는 일입니다. 여기서 차 한 대가 모델 한 줄, 시승 기록이 칸마다 채울 숫자입니다.
| 칸 | 무엇을 적나 | 쉽게 말하면 |
|---|---|---|
| 정답(/20) | 규정에 있는 질문 20개 가운데 맞힌 수 | 길을 제대로 찾아갔나 |
| 출처 맞음(/20) | 답에 근거 조항을 바르게 단 수 | 어느 길로 왔는지 말할 수 있나 |
| 지나친 거절 | 답이 있는데 "모른다"고 한 수 | 갈 수 있는 길인데 안 간다고 한 횟수 |
| 모름 맞음(/5) | 규정에 없는 질문 5개에 "모른다"고 한 수 | 없는 길을 지어내지 않았나 |
| 25문항 초 | 25문항에 걸린 시간(초) | 걸린 시간 |
| 라이선스 | 쓸 수 있는 조건 | 회사 차로 써도 되나 |
이 코드의 출력은 칸 이름 목록뿐입니다. 숫자는 프로젝트에서 모델마다 같은 질문을 물어 직접 채웁니다.
주의할 점
- 공개 순위표의 점수는 영어나 일반 문제 기준인 경우가 많습니다. 우리 언어와 우리 문서에서의 성적은 직접 재야 압니다.
- 여러 모델을 잇달아 띄우면 앞의 모델이 GPU 를 차지해 뒤 모델이 CPU 로 넘어갑니다(6장). 모델마다 시간을 재기 전에 앞의 모델을 내립니다.