한 번에 잡는 NLP/LLM/RAG 개념 지도

자연어 처리

by 짧은 수필

1) 먼저, 핵심 지도를 머릿속에 그려보자


청크화(Chunking)는 긴 문서를 검색/입력 한도에 맞춰 큰 조각(보통 500~1500자)으로 쪼개는 과정입니다. RAG에서 검색의 기본 단위가 됩니다.


토큰화(Tokenization)는 텍스트를 모델이 이해하는 숫자 토큰(ID)으로 바꾸는 과정입니다. 모델 입·출력 직전에 항상 일어납니다.


Hugging Face는 모델·토크나이저·데이터셋을 제공하는 저수준 라이브러리/허브입니다.


LangChain은 RAG/에이전트/체인 등 LLM 앱을 빠르게 만드는 파이프라인 프레임워크입니다.


RAG는 검색(Retrieval)+생성(Generation) 전략입니다. 긴 문서를 검색으로 보강해 환각을 줄이고 최신/사내 지식을 답변에 끌어옵니다.


현대 LLM의 계보는 머신러닝 → RNN → Transformer → LLM → 멀티모달 LLM으로 이어집니다.



전체 파이프라인은 보통 이렇게 흐릅니다:
수집 → 청크화 → 임베딩·벡터DB → 질의 임베딩 → Top-k 검색 → 선택 청크 + 질문 토큰화 → LLM 생성




2) 청크화와 토큰화: 비슷한 듯 하지만, 완전히 다르다


청크화(Chunking)가 필요한 이유

문서는 보통 모델이 한 번에 읽기엔 너무 깁니다. 또한 검색 정확도를 높이려면 “적당한 길이의 덩어리”로 나눠야 하죠. 그래서 문단·문서 조각 같은 단위로 미리 쪼갭니다.

예시: 2,500자짜리 기사 한 편을 1,000자 청크로 자르고 겹침(overlap) 100자를 둡니다.
이렇게 하면 의미가 경계에서 끊어지지 않고, 검색 매칭도 안정적입니다.


토큰화(Tokenization)는 언제 일어나는가

모델은 텍스트를 바로 다루지 못합니다. 입력 직전에 문장을 토큰 단위로 쪼개고, 각 토큰을 정수 ID로 바꾸죠.
BERT 기준으로 "Hello world!"는 대략 [101, 7592, 2088, 999, 102] 같은 시퀀스로 바뀝니다.

이후 모델의 첫 레이어(임베딩 레이어)가 이 정수들을 실수 벡터로 바꿉니다.


정리: 청크화는 “검색/입력 최적화용 큰 덩어리 나누기”, 토큰화는 “모델이 읽도록 숫자로 바꾸기”입니다.




3) RAG는 어떻게 동작할까? (파이프라인 한눈에)


원문 수집: 웹, PDF, 위키, 사내 문서 등


청크화: 긴 문서를 800 ~ 1500자 등으로 나눔 (필요시 50 ~ 200자 겹침)


임베딩 & 벡터DB: 각 청크를 문장 임베딩 모델로 벡터화해 벡터DB(예: FAISS)에 저장


질문 임베딩: 사용자의 질문도 같은 임베딩 모델로 벡터화


Top-k 검색: 질문 벡터와 가까운 청크 k개(예: 3)를 꺼냄


LLM 입력: 선택된 청크들을 질문과 함께 토큰화해서 LLM에 넣음


생성: LLM이 근거를 참고해 답변을 종합해서 생성


여기서 중요한 오해가 하나 있어요.
k=3이라고 하면 “3개 후보 중 1개를 고른다”가 아닙니다.
가장 관련성 높은 청크 3개를 전부 참고해, 종합된 답변을 생성합니다.




4) Hugging Face / LangChain / RAG는 누가 뭐 하는가

Hugging Face: 모델과 토크나이저, 데이터셋이 모여 있는 생태계/허브입니다. transformers, datasets, tokenizers로 모델을 직접 제어하고 파인튜닝/추론을 수행합니다. “엔진/부품”에 가깝습니다.


LangChain: LLM을 실제 서비스로 엮는 프레임워크입니다. 프롬프트 체이닝, 벡터DB 연결, 툴 사용, 에이전트 등 앱 파이프라인을 추상화합니다. “차를 조립하는 툴”에 가깝습니다.


RAG: 긴 맥락과 최신성을 확보하기 위한 전략/아키텍처입니다. 검색된 근거를 LLM에 공급해 정확한 생성을 유도합니다. “운전 전략”에 가깝습니다.




5) NLP → LLM: 시대별 흐름 요약


규칙 기반(’80~’00s): 사람이 규칙과 사전을 만들던 시절


전통 머신러닝(’00~’15): TF-IDF, SVM, CRF 등. 피처 엔지니어링이 핵심


딥러닝 RNN 시대(’13~’17): Word2Vec/Glove, LSTM/GRU. 순서 모델링은 가능하지만 긴 문맥이 약점


Transformer(’17~’20): Attention으로 병렬 처리와 긴 문맥 이해. BERT/GPT의 등장


LLM(’20~): 거대 사전학습 + RLHF. 범용 능력과 대화성


멀티모달(’23~): 텍스트+이미지(+음성/영상). GPT-4o, Gemini 등




6) 모델 유형을 쓰임새로 기억하기

Encoder-only (BERT, RoBERTa, ALBERT): 분류/추출/문서 이해


Decoder-only (GPT, LLaMA, Claude): 생성/대화/RAG의 생성부


Encoder-Decoder (T5, BART, mBART): 번역/요약/복원(문장→문장 변환)


Multimodal (GPT-4o, Gemini 등): 텍스트+이미지(+음성) 융합




7) 모델 내부에서는 무슨 일이 벌어질까?

토큰화: 텍스트 → 정수 토큰 ID(대개 서브워드/BPE)


임베딩: 토큰 ID → 고차원 벡터(모델 첫 레이어)


Transformer: Self-Attention, FFN, LayerNorm이 여러 층 반복되어 문맥을 반영


생성/분류:
- 생성형(GPT류)은 자동회귀로 “다음 토큰 확률”을 예측하며 한 토큰씩 생성
- 분류/추출은 최종 벡터를 태스크 헤드에 연결


디토큰화: 토큰 ID → 텍스트로 되돌림


RAG에서 말하는 “임베딩 모델”은 이 중 표현(벡터)만 잘 뽑는 모델을 별도로 써서, 질문과 문서(청크)의 의미 유사도를 계산하는 데 사용합니다.




8) 실전 노하우: 청크, 검색, 임베딩, 프롬프트


청크 설정 가이드

뉴스/블로그: chunk_size 800~1200, overlap 50~100

매뉴얼/논문/코드: 1000~1500, overlap 100~200

짧은 문서가 많다면: chunk_size를 크게(≥2000) 해서 문서를 그대로 한 청크로


Top-k 검색

k=1: 간결하고 빠르지만 누락 위험

k=3~5: 일반적으로 추천

k>8: 길이/잡음 증가로 오히려 혼란 가능


임베딩 모델 선택

“질문 ↔ 컨텍스트” 매칭에는 문장 임베딩(예: e5, Instructor, text-embedding 계열 등)이 잘 맞습니다.


프롬프트 수호 규칙

근거가 없으면: “주어진 정보에서 찾을 수 없습니다.”

출처(URL)를 함께 노출해 신뢰성 확보


흔한 함정

청크가 너무 크면 토큰 초과/중복이 생기고, 너무 작으면 문맥 파편화가 일어납니다.

잘못된 토큰화/인코딩은 한글 깨짐과 길이 계산 오류를 부릅니다.




9) 아주 간단한 RAG 코드 스케치 (LangChain)

# 1) 청크화
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = splitter.split_documents(docs) # docs: (source, page_content) 형태


# 2) 임베딩 & 벡터DB
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
vecdb = FAISS.from_documents(chunks, OpenAIEmbeddings())


# 3) 검색기 & RAG 체인
retriever = vecdb.as_retriever(search_kwargs={"k": 3})
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system",
"{summaries} 해당 웹페이지 정보에서 찾을 수 없다면 "
"\"주어진 정보에서 찾을 수 없습니다.\" 출력"),
("human", "{question}")
])

from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQAWithSourcesChain
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)

chain = RetrievalQAWithSourcesChain.from_chain_type(
llm=llm, retriever=retriever, chain_type_kwargs={"prompt": prompt}
)


# 4) 질의
out = chain.invoke({"question": "무슨 내용이야?"})
print(out.get("answer") or out.get("result"))
print(out.get("sources") or out.get("source_documents"))

실제 서비스에선 에러 처리, 출처 예쁘게 출력, 토큰 길이 관리, 캐시/재시도 등이 더해집니다.




10) 마무리: 한 문장으로 기억하세요


청크화는 검색과 입력 한도를 위한 큰 단위 나누기,


토큰화는 모델이 읽도록 숫자 토큰으로 바꾸는 단계.


Hugging Face는 엔진/부품, LangChain은 앱 파이프라인, RAG는 검색+생성 전략.


현대 LLM은 토큰화 → 임베딩 → Transformer로 동작하고,
RAG는 여기에 벡터 검색을 더해 긴 문서의 기억을 보강합니다.


keyword
매거진의 이전글텍스트 데이터 분석, 어디서부터 어떻게 할까?