728x90
반응형

오늘은 대규모 언어 모델(LLM) 이 사람들의 복잡한 지시를 더 잘 이해하고 수행하도록 만드는 방법을 다룬 흥미로운 논문, WizardLM을 소개해보려고 합니다. 우리가 ChatGPT 같은 모델을 쓰다 보면 이런 경험 있죠?

“이 모델… 말은 잘하는데, 내 요구를 정확히 이해한 건가…?”

이 문제의 핵심은 바로 Instruction Tuning(지시문 학습)입니다.

리고 WizardLM은 여기서 한 단계 더 나아가 “AI가 스스로 더 어려운 지시문을 만들어서 학습한다”는 아이디어를 제시합니다.

 

사실 이 논문은 2023년에 나온 꽤 오래된 논문인데요..! LLM을 공부하다 보면 자연스레 합성 데이터 생성에 대해 관심이 많아지고 이 논문은 그 합성 데이터 생성의 혁신을 불러일으킨 논문입니다.


1. Abstract

기존 LLM은 대규모 텍스트로 학습되었지만, 사람들의 복잡한 지시를 안정적으로 따르는 능력은 충분하지 않았습니다.

그래서 등장한 것이 Instruction Tuning —사람이 작성한 “지시문 + 답변” 데이터로 모델을 추가 학습시키는 방식이죠.

하지만 여기엔 큰 문제가 있습니다.

  • 사람이 고품질 지시문을 만드는 데 시간과 비용이 너무 많이 든다
  • 특히 복잡한 지시문은 더 만들기 어렵다

👉 그래서 WizardLM은 이런 질문을 던집니다.

“사람 대신, LLM이 스스로 점점 더 어려운 지시문을 만들어 학습하면 안 될까?”

 

이 아이디어를 구현한 방법이 바로 Evol-Instruct 입니다.


2. Introduction — 왜 ‘복잡한 지시’가 중요할까?

기존 instruction 데이터는 이런 특징이 있습니다.

  • 비교적 단순한 요청
  • 단일 작업 위주 (요약, 번역, 분류 등)
  • 현실 세계에서 쓰이는 복합적인 요구를 충분히 반영하지 못함

하지만 실제 사용자 요청은 이런 식이죠:

“이 글을 요약해주고, 초등학생도 이해할 수 있게 바꿔서, 마지막에 핵심만 bullet point로 정리해줘.”

 

이건 단순 요역이 아니라 요약, 난이도 조절, 형식 변환이 한 번에 들어간 복합 지시입니다.

 

WizardLM은 바로 이런 복잡도 높은 instruction을 대량으로 만드는 방법에 집중합니다.


3. Method — Evol-Instruction란 무엇인가?

아래 그림부터 보시면, Evol-Instruction에 대해 감을 잡을 수 있을겁니다..!

WizardLM 논문 그림1

감이 오시나요? Figure 1은 Evol-Instruct의 실행 예시로서 간단한 초기 지시문

1 + 1 = ?

 

에서 시작하여, 복잡한 지시문으로 업그레이드하거나 새로운 지시문을 생성하기 위해 In-depth Evolving or In-breadth Evolving을 무작위로 선택합니다.

  • In-depth Evolving: 제약 조건 추가, 심화, 구체화, 추론 단계 증가, 입력 복잡화의 다섯 가지 유형의 연산을 포함하여 복잡한 데이터셋을 확보합니다.
  • In-breadth Evolving: 주어진 지시문을 기반으로 완전히 새로운 지시문을 생성하는 방법으로 데이터셋의 다양성을 확보합니다.

이러한 진화 과정을 통해 생성된 데이터는 단순히 양만 늘어나는 것이 아니라, 다양한 난이도와 주제를 포괄하는 풍부하고 복잡한 지시 데이터셋을 만듭니다. 또한, 실패한 진화(Instruction Eliminator)를 걸러내는 과정을 통해 데이터의 품질을 유지합니다.

 

구체적인 과정은 아래 그림을 통해 확인할 수 있습니다:

wizardLM 그림 2

이 과정은 크게 세 가지 핵심 단계로 구성됩니다.

각 단계는 LLM의 생성 능력과 미리 정의된 진화 전략을 활용해 instruction 데이터셋을 점점 더 풍부하게 만듭니다.

먼저 출발점부터 보겠습니다.

초기 데이터셋: D(0)

이는 사람이 만든 소량의 instruction 데이터 또는 기존 자동 생성 데이터(예: Alpaca의 seed instruction)로 구성됩니다.

 

수식으로 표현하면 다음과 같습니다.

 

D(0) = { (I(0)ₖ, R(0)ₖ) }

  • I(0)ₖ : k번째 초기 지시문
  • R(0)ₖ : 그 지시에 대한 응답

즉, 아주 기본적인 (지시, 응답) 쌍들의 집합이 시작점입니다.


1단계: Instruction Evolver — 지시문 진화

이 단계의 목표는 기존 지시문을 더 어렵거나 더 다양하게 바꾸는 것입니다.

① 데이터셋에서 지시문 선택

초기 데이터셋 D(0)에서 각 지시문 I(0)ₖ 를 하나씩 가져옵니다.

② 진화 전략 무작위 선택

각 지시문마다 두 가지 진화 방향 중 하나를 무작위로 선택합니다.

논문에서는 여러 프롬프트 템플릿 중 하나를 균등 확률로 선택합니다.

  • In-depth Evolving (난이도 상승)
  • In-breadth Evolving (다양성 확장)

🔬 In-depth Evolving (난이도 증가)

기존 instruction을 유지한 채 점점 더 복잡하게 만듭니다.

사용되는 진화 유형 예시:

  • 제약 조건 추가
  • 더 구체적인 상황 설정
  • 여러 단계의 추론 요구
  • 입력 정보 복잡화
  • 설명 과정 요구

즉, “같은 문제를 더 어렵게” 만드는 방향입니다.


🌐 In-breadth Evolving (다양성 증가)

이번에는 기존 지시와 유사하지만, 완전히 새로운 주제/작업의 instruction을 생성합니다.

 

즉, 데이터셋이 특정 유형에 치우치지 않도록 주제와 작업 범위를 넓히는 역할을 합니다.


③ LLM에게 진화 요청

선택된 진화 전략에 맞는 프롬프트와 함께 기존 지시문 I(0)ₖ 를 LLM(논문에서는 ChatGPT API 사용)에게 전달합니다.

 

LLM은 이를 바탕으로 새로운 지시문 I(1)ₖ 를 생성합니다.


2단계: Response Generation — 답변 생성

이제 진화된 instruction I(1)ₖ 이 준비되었습니다.

이 지시문을 다시 LLM에 입력하여 해당 지시에 대한 응답 R(1)ₖ 를 생성합니다.

이 단계가 중요한 이유는,

사람이 정답을 작성하는 것이 아니라

LLM이 스스로 “문제 + 모범 답안”을 동시에 만드는 구조이기 때문입니다.

 

이렇게 해서 새로운 학습 데이터 쌍 (I(1)ₖ, R(1)ₖ) 이 만들어집니다.


🧹 3단계: Instruction Eliminator — 진화 실패 필터링

하지만 모든 진화가 성공적인 것은 아닙니다.

그래서 생성된 데이터는 자동 필터링 단계를 거칩니다.

❌ 진화 실패로 판단되는 경우

  • 정보가 부족해 의미 있는 instruction이 되지 않은 경우
  • 응답 생성이 사실상 불가능한 경우
  • 의미 없는 텍스트가 생성된 경우
  • 프롬프트 문장을 그대로 복사한 경우

이런 샘플은 “진화 실패”로 간주됩니다.


✅ 성공/실패에 따른 처리

  • 성공한 경우
  • → (I(1)ₖ, R(1)ₖ) 쌍을 유효한 데이터로 저장
  • 실패한 경우
  • → 데이터셋에 추가하지 않고, 필요 시 다음 라운드에서 다시 진화 시도 가능

논문에서는 성공한 instruction은 데이터 풀에 추가하고, 실패한 instruction은 다시 시도 대상으로 남겨둔다고 설명합니다.


다음 라운드로 반복 진화

이제 성공적으로 필터링된 데이터들로 새로운 데이터셋을 구성합니다.

 

D(1) = { (I(1)ₖ, R(1)ₖ) | 진화 성공한 샘플 }

 

그리고 이 D(1)을 다시 입력으로 사용해 1단계 → 2단계 → 3단계 과정을 반복합니다.

논문에서는 이 진화 과정을 여러 라운드(예: 4 epochs) 반복합니다.

 

즉,

D(0) → D(1) → D(2) → … → D(M)

 

형태로 instruction이 점점 더 복잡하고 다양해집니다.


최종 단계: Fine-tuning 데이터셋 구축

모든 진화 라운드가 끝나면,

  1. 모든 라운드의 성공 데이터 통합
  2. → D(0), D(1), …, D(M)을 하나의 큰 데이터셋으로 합침
  3. 셔플(무작위 섞기)
  4. → 학습 순서 편향 방지
  5. 필요 시 샘플링동일한 데이터 양(예: 70K 샘플)을 무작위로 추출해 사용
  6. 논문에서는 기존 모델(Vicuna 등)과 공정 비교를 위해

이 최종 데이터셋으로 LLM을 Instruction Tuning 하면 바로 WizardLM이 됩니다.


4. Experiments — 그래서 성능은 얼마나 좋아졌을까?

아무리 데이터 생성 방식이 멋져도, 결국 중요한건 “그래서 모델이 실제로 더 똑똑해졌는가?” 입니다.

논문에서는 WizardLM의 성능을 검증하기 위해 기존 오픈소스 모델들과 비교 실험을 진행합니다.

1) Human Evaluation (사람 평가)

사람 평가자는 두 모델의 답변을 보고 더 나은 쪽을 선택합니다.

평가 기준은 다음과 같습니다.

  • 지시 이해 정확도
  • 답변의 유용성
  • 논리적 일관성
  • 복잡한 요청 처리 능력

결과는 꽤 인상적입니다.

WizardLM은 기존 오픈소스 모델들보다 더 자주 선호되었고,

특히 복잡한 multi-step instruction에서 강점을 보였습니다.

 

즉, Evol-Instruct로 학습한 데이터가 정말로 “말귀 잘 알아듣는 능력”을 키워준 셈입니다.

 

wizardLM 표 1

2) Automatic Evaluation (자동 평가)

자동 평가에서는 모델이 다양한 지시를 얼마나 잘 수행하는지 테스트합니다.

 

여기서도 WizardLM은 다음과 같은 특징을 보였습니다.

✔ 단순 작업뿐 아니라 조건이 많은 복합 지시에서 강함

✔ 단계적 추론이 필요한 문제에서 성능 향상

✔ 형식 요구가 있는 출력(예: 표, 리스트 등)에서도 안정적

 

즉, 단순히 말 잘하는 모델이 아니라 “지시를 제대로 수행하는 모델”에 가까워졌다고 볼 수 있습니다.

 

wizardLM 그림 4

 

흥미로운 관찰 포인트

이 논문에서 가장 인상적인 부분은 바로 이것입니다.

🧠 사람이 직접 만든 instruction 데이터보다 🤖 AI가 진화시켜 만든 instruction 데이터가 더 효과적이었다

 

이건 꽤 큰 메시지를 줍니다.

 

우리는 보통 “사람이 만든 데이터 = 고품질” 이라고 생각하지만, WizardLM은 “잘 설계된 AI 생성 데이터도 그에 못지않게 강력하다”는 걸 보여준 사례입니다.


5. Discussion — 이 연구가 중요한 이유

WizardLM의 기여는 단순히 모델 성능 개선이 아닙니다.

LLM 학습 방식 자체의 방향성을 바꿨다는 점이 핵심입니다.

기존 패러다임

사람이 데이터 만들고 → 모델이 학습

WizardLM이 보여준 새로운 방향

모델이 더 좋은 학습용 데이터를 만들고 → 그 데이터로 모델이 더 똑똑해짐

 

즉, 모델이 단순 소비자가 아니라 학습 데이터의 생산자 역할까지 하게 된 것입니다.

 

이 아이디어는 이후 등장한 많은 합성 데이터 기반 연구들에 직접적인 영향을 주었습니다.


6. Limitations — 그래도 한계는 있다

물론 이 방법이 완벽한 것은 아닙니다.

논문에서도 몇 가지 한계를 언급합니다.

  • 생성된 instruction의 품질은 여전히 LLM 성능에 의존
  • 잘못 설계된 프롬프트는 데이터 품질 저하로 이어질 수 있음
  • 진화가 반복될수록 오류도 함께 증폭될 가능성

즉,

AI가 만든 데이터가 항상 정답은 아니다

라는 점은 여전히 중요합니다.


마무리 — WizardLM을 한 줄로 정리하면

WizardLM은 단순한 모델이 아니라,

“AI가 스스로 더 어려운 문제를 만들며 성장하는 학습 방식”

을 제시한 연구입니다.

 

이 논문 이후로 LLM 학습에서 합성 데이터(Synthetic Data)는 선택이 아니라 거의 필수 전략처럼 자리 잡게 되었습니다.

 

개인적으로 LLM 학습 공부를 하고 있는 입장에서 wizardLM을 쓴 것과 쓰지 않았을때의 실험을 진행해 볼 예정입니다.

 

이것도 많은 관심 부탁 드립니다. 감사합니다!!

 

 

728x90
반응형
728x90
반응형

2026년도 1월이 벌써 절반이 지나갔습니다.

지금부터라도 매주 일요일마다 다음 주를 위한 계획을 세우고,

지난 한 주를 돌아보는 기록을 남기려 합니다.

이 기록은 AI Research Engineer의 성장 로그를 남기기 위한 주간 리포트입니다.

매주 일요일마다:

  • 지난 주를 회고하고
  • 다음 주의 목표를 명확히 하며
  • 기술적으로 무엇을 다뤘는지 기록합니다.

1. 다음 주 계획 (1월 19일 ~ 1월 25일)

 

💼 업무 (회사)

  • 그룹사 2곳 Apps SDK 테스트 완료

📚 학습 / 연구

  • 처음하는 파이썬 백엔드 FastAPI 입문 강의 수강
  • 파이썬 입문 & 크롤링 기초 부트캠프 강의 수강
  • Single GPU 환경에서 PEFT 코드 체화

🧠 자기관리

  • 퇴근 후 신문 읽기
  • 주 5회 이상 헬스장 출석
  • 유산소 운동 주 5회
  • 영양제 챙겨 먹기
  • 다이어트 루틴 유지

2. 이번 주 회고

💼 업무 (회사)

  • 그룹사 2곳 MCP 서버 구축
  • 1곳은 배포까지 완료
  • LLM Benchmark Evaluation 개발 진행

📚 학습 / 연구

  • FastAPI 입문 강의 11개 수강 완료
  • 파이썬 입문 & 크롤링 기초 부트캠프 강의 시작

🧠 자기관리

  • [x] 퇴근 후 신문 보기
  • [x] 주 5회 이상 헬스장 출석
  • [x] 유산소 주 5회
  • [x] 영양제 챙겨 먹기
  • [ ] 다이어트는… 😅

3. 다음 주 다짐

기록하자. 체력 관리 잘하자.

728x90
반응형
728x90
반응형

오랜만에 티스토리에 글을 남긴다.

 

돌아보면, 2025년은 내 커리어에서 여러 갈림길이 겹쳐 있던 해였다.

 

증명하고, 준비하고, 연결된 해.

해당 이미지는 ChatGPT를 통해 생성한 이미지입니다.

 

연구자로서 붙잡아 온 문제의식이 하나의 결과로 확정되었고, 그 결과를 발판 삼아 산업계로 나아가기 위한 준비를 본격적으로 시작했다. 그리고 여름에 참여한 하나의 프로젝트가 사람과의 인연으로 이어지며, 결국 지금의 자리까지 자연스럽게 연결되었다.


증명 — 연구자로서의 마침표

NAACL 2025 논문은 2025년에 시작된 일이 아니었다.

해당 이미지는 ChatGPT를 통해 생성한 이미지입니다.

 

 

2024년 10월 ACL ARR에 논문을 제출했고, 11월에 받은 리뷰 결과는 예상보다 긍정적이었다. 그 흐름을 이어 12월에 NAACL로 리서브밋했고, 2025년 1월 말 최종 Accept를 받았다.

 

그 순간의 감정은 단순한 성취감보다는 확인에 가까웠다.

 

논리적 오류 탐지와 프롬프트 설계, 그리고 LLM의 신뢰성과 한계를 집요하게 분석하던 연구 방향이 틀리지 않았다는 것을 외부로부터 검증받았다는 느낌이었다. 이 논문은 나에게 하나의 성과이자, 동시에 연구자로서 한 챕터를 정리하는 마침표였다.

 

진짜… 1월 말 결과가 나오기전까지 매일 Reddit에 들락나락 거리며 내가 될까.. 될까…

 

그 어떤 일에도 집중할 수 없었다.


준비 — 다음 단계를 향한 시간

연구가 하나의 결과로 마무리되자, 자연스럽게 다음 질문이 생겼다.

“이 연구 감각을 산업 환경에서도 계속 가져갈 수 있을까?”

 

상반기 동안 나는 산업계로의 진입을 진지하게 고민하며 취업 준비를 병행했다.

 

단순히 지원서를 쓰는 시간이 아니라, 내가 어떤 문제를 풀고 싶은지, 연구에서 중요하게 여겼던 관점을 실제 시스템과 서비스 안에서 어떻게 적용할 수 있을지를 계속해서 정리해 나가는 과정이었다.

 

이 시기는 불확실했지만, 동시에 필요했던 시간이었다.

 

연구자에서 실무로 이동하기 위해 어떤 준비가 필요한지를 스스로에게 묻고 답하던 구간이었다.


연결 — 프로젝트가 기회가 되다

여름방학이 시작되면서 카카오 테크포임팩트 B-PEACH LAB에 참여했다.

 

해당 이미지는 ChatGPT를 통해 생성한 이미지입니다.

 

느린 학습자를 위한 번안기 프로젝트를 진행하며, 기술적인 구현뿐만 아니라 문제를 정의하는 방식과 실제 사용자를 고려하는 시각의 중요성을 다시 한 번 느꼈다.

 

이 프로젝트를 통해 만난 분과의 인연이 뜻밖의 제안으로 이어졌다.

 

“회사에 한 번 지원해보지 않겠냐”는 제안은 갑작스러웠지만, 그동안 쌓아온 고민과 준비 덕분에 자연스럽게 받아들일 수 있었다. 그렇게 지원을 진행했고, 2025년 9월 15일부터 현재 회사에 입사해 근무하게 되었다.


적응 — 연구 감각을 실무에 놓다

입사 이후의 시간은, 내가 쌓아온 연구적 사고를 실제 조직과 시스템 안에 올려보는 과정이었다.

 

해당 이미지는 ChatGPT를 통해 생성한 이미지입니다.

 

처음부터 빠르게 성과를 내기보다는, 이 환경에서 어떤 문제가 중요하게 다뤄지는지, 그리고 내가 어떤 질문을 던질 수 있는지를 이해하는 데 집중했다.

 

입사 직후부터 11월 말까지는 토이 프로젝트를 중심으로 움직였다.

 

한국어 LLM의 hallucination을 구조적으로 정의하고 평가하는 작은 프로젝트로,

모델이 언제, 어떤 이유로 신뢰할 수 없는 출력을 내놓는지를 분류하고 정리하는 데 초점을 맞췄다.

 

이 과정은 단순한 실습이 아니라, 실무에서 문제를 다룬다는 것이 무엇을 의미하는지를 배우는 시간이었다.

 

정의되지 않은 문제는 해결할 수 없고, 작은 기준 하나가 이후의 판단과 설계를 크게 좌우한다는 사실을 체감했다.

 

12월에 들어서면서부터는 GPT-OSS-120B 모델을 Unsloth와 H100 80GB 단일 GPU 환경에서 QLoRA로 학습하며, 대형 LLM의 실제 학습 환경을 직접 마주하게 되었다.

 

논문이나 개인 프로젝트에서는 설명으로 충분했던 문제들이, 실무에서는 반드시 결과로 이어져야 했다. 모델은 돌아가야 했고, 학습은 명확한 제약 안에서 이루어져야 했으며, 선택 하나하나에는 비용과 책임이 따랐다.

 

이 경험을 계기로, 단일 GPU 환경을 넘어 멀티 GPU와 분산 학습 환경에서도 재사용 가능한 학습 구조가 필요하다는 문제의식이 생겼다. 이후에는 분산 학습을 직접 구현하고, 다양한 실험에 반복해서 활용할 수 있는 템플릿 형태의 학습 코드를 만들어두는 것을 목표로 삼게 되었다.

 

현재 DP와 DDP에 대한 이론 공부를 하고 DDP 코드 구현을 완료했다..!


2025년이 남긴 것

2025년은 나에게 많은 것을 바꿔놓은 해라기보다, 하나의 흐름을 완성시킨 해였다.

 

연구자로서 나를 증명했고, 산업계로 가기 위한 준비를 했으며, 하나의 프로젝트와 인연이 실제 커리어로 연결되었다. 그리고 입사 이후의 시간은, 그 선택이 우연이 아니었음을 확인하는 과정이었다.

 

이제 나는 질문만 던지는 사람이 아니라, 그 질문에 대해 현실적인 답을 만들어야 하는 위치에 서 있다.

 

2026년에는 이 역할에 더 익숙해지고, 더 책임 있게 답할 수 있는 사람이 되고 싶다.


2026년을 향해 — 질문에 책임을 더하다

2026년에는, 지금까지 던져 온 질문들에 더 큰 책임을 지고 답하는 사람이 되고 싶다.

 

연구에서는 “왜 이런 현상이 발생하는가”를 설명하는 데 집중했다면, 이제는 실무에서 “그래서 이 선택이 어떤 결과를 만드는가”까지 함께 고민해야 하는 위치에 서게 되었다고 느낀다.

 

첫째, 대형 LLM을 더 깊이 이해하는 엔지니어가 되고 싶다.

 

모델 구조나 학습 기법을 아는 데서 그치지 않고, 단일 GPU 환경에서의 한계를 경험한 이후, 멀티 GPU와 분산 학습 환경까지 고려해 재사용 가능한 학습 구조를 설계하고 설명할 수 있는 수준에 도달하고 싶다.

 

단순히 “돌아가는 코드”가 아니라, 왜 그런 선택을 했는지, 어떤 트레이드오프가 있었는지를 명확히 말할 수 있는 구현을 목표로 한다.

둘째, 신뢰성과 실패를 다루는 감각을 실무 수준으로 끌어올리고 싶다.

 

논문에서는 분석으로 끝났던 failure case들이, 실무에서는 곧바로 사용자 경험과 리스크로 이어진다.

 

2026년에는 모델의 한계를 인지한 상태에서 설계하고, 문제가 발생했을 때 재현·분석·완화까지 이어지는 흐름을 스스로 책임질 수 있는 사람이 되고 싶다.

 

“왜 틀렸는지 아는 사람”을 넘어, “그래서 어떻게 대응할지 결정할 수 있는 사람”으로 성장하는 것이 목표다.

셋째, 연구와 실무를 연결하는 언어를 계속 만들어가고 싶다.

 

논문, 블로그, 문서화 등 어떤 형태든, 내가 고민한 문제와 선택의 이유를 남기고 공유하고 싶다.

연구자와 엔지니어 중 하나를 택하기보다는, 두 세계를 오가며 같은 질문을 다른 조건과 책임 아래에서 던질 수 있는 위치를 유지하는 것이 나의 방향이다.

 

동시에, 실무를 병행하더라도 연구자로서의 질문을 완전히 내려놓지는 않고 싶다.

 

퇴근 이후의 시간에도 꾸준히 공부를 이어가며, 토이 프로젝트에서의 경험을 발판 삼아 할루시네이션이라는 문제를 더 넓은 관점에서 다루는 연구를 동기와 함께 완주하고 싶다.

 

실무에서 마주하는 실패와 불안정성을 연구의 언어로 다시 정리하고, 그것을 하나의 논문으로 남기는 과정 자체가 2026년의 중요한 목표다.

궁극적으로는, 2026년이 끝날 즈음

“이 문제는 이 사람이 제일 잘 안다”

는 인식이 자연스럽게 형성되는 위치에 서고 싶다.

 

특정 모델이나 코드 한 줄이 아니라, LLM 학습과 안정성, 그리고 실패를 다루는 전체 맥락을 함께 고민할 수 있는 사람으로 신뢰받는 것이 목표다.

 

그 신뢰가 역할로 이어지고, 역할이 책임으로 이어질 때, 보상은 결과로 따라온다고 믿는다.

 

2025년이 하나의 흐름을 완성한 해였다면, 2026년은 그 흐름 위에서 속도를 내는 해가 되었으면 한다.

 

아직은 부족하지만, 어떤 질문을 붙잡고 가야 하는지는 분명해졌다.

 

그 질문을 끝까지 놓지 않는 한 해를 만들어보고 싶다.

728x90
반응형
728x90
반응형

안녕하세요!😊

최근까지 테디노트 RAG 비법노트 정리와 Agent 관련 글을 열심히 쓰고 있었는데, 오늘은 잠시 그 연재를 멈추기로 했습니다.

이유는 단 하나—요즘 제가 정말 강하게 끌리는 분야가 생겼기 때문입니다.

바로 LLM(대규모 언어 모델) 그 자체를 깊이 있게 공부하는 일입니다.

해당 이미지는 ChatGPT가 생성했습니다.


알고 보니, 내가 진짜 관심 있는 건 “모델 내부”였다

Transformer가 어떻게 작동하는지, Attention이 무엇인지,

이런 기본적인 구조는 이미 이해하고 있습니다.

그런데 프로젝트를 진행하면서 깨달은 것이 있습니다.

“내가 진짜 알고 싶은 건, LLM이 어떻게 훈련되고,왜 이런 응답을 하고,어떤 요소들이 성능을 좌우하는가 하는 부분이구나.”

 

RAG, Agent, LangChain—all fun.

 

하지만 결국 근본은 언어 모델 자체를 이해하는 일이라는 생각이 점점 강해졌습니다.


🔥 앞으로는 이런 내용들을 탐구하려고 합니다

단순한 Transformer 개념이 아니라,

“실제 LLM이 어떻게 구성되고 운영되는지”에 초점을 맞춥니다.

1) LLM의 학습 과정 깊이 이해하기

  • Pretraining 실제 데이터 구성 방식
  • SFT가 모델에 주는 영향
  • RLHF / DPO가 왜 모델의 성향을 바꾸는가
  • Instruction-following 능력의 원천

2) Parameter-efficient Training(PEFT)의 실제 영향

  • LoRA / QLoRA가 어떤 레이어를 바꾸는가
  • 랭크(rank) 변화가 성능에 어떤 영향을 주는가
  • Adapter 방식과의 차이

3) 모델별 아키텍처 차이 분석

  • LLaMA vs Qwen vs Mixtral vs GPT 구조 비교
  • RoPE 스케일링 방식 차이
  • GQA(그룹드 쿼리 어텐션)가 왜 메모리를 아끼는지
  • Mistral이 왜 효율적인지를 수식 없이 이해하기

4) 실제 모델 실험

  • 다양한 한국어 모델 벤치마크
  • hallucination 분석
  • embedding 품질 비교(BGE vs e5 vs OpenAI)
  • 미니 데이터로 파인튜닝 실험

5) LLM 생태계 흐름 이해

  • 오픈소스 모델 발전 추세
  • 상용 모델이 선택하는 방향성
  • 한국 모델이 갖는 특징과 과제
  • Reasoning 모델..!

그래서 지금 글쓰기 방향을 잠시 바꿉니다

RAG와 Agent는 앞으로도 계속 다룰 예정입니다.

하지만 당분간은 제가 진짜 궁금한 것, 즉 “LLM이 어떻게 만들어지고 움직이는지”에 집중하려 합니다.

이건 “기초로 돌아가는 것”이 아니라 제가 가장 흥미를 느끼는 분야로 자연스럽게 확장하는 과정이라고 생각합니다.


📝 마무리

지금 제 관심은 단순히 LLM 사용 방법이 아니라

LLM 그 자체에 있습니다.

“모델을 깊이 이해해야 진짜 좋은 RAG도, 좋은 Agent도 만든다.”

 

앞으로는 LLM 연구·엔지니어링 관점의 글들을 중심으로 더 풍부한 내용을 정리해 나갈 계획입니다.

 

 

 

관심 있는 분들은 함께 탐구합시다.

 

읽어주셔서 감사합니다 🙏

728x90
반응형
728x90
반응형

어제는 AI Agent가 어떻게 발전해왔는지, CoT → ReAct → Agentic Architecture로 이어지는 흐름을 정리했습니다.

오늘은 실제 에이전트를 구성할 때 중요한 프레임워크인 LangGraph의 핵심 개념과 구조를 살펴보겠습니다.


LangGraph란 무엇인가?

LangGraph는 “상태(State)를 기반으로 한 에이전트의 사고 흐름을 그래프로 표현하는 프레임워크” 입니다.

일반적인 LLM 호출은 다음과 같은 단일 요청-응답 구조입니다:

Input → LLM → Output

하지만 에이전트는 작업을 한 번에 끝내지 않습니다.

계획 → 행동 → 반성 → 반복 의 과정을 거치며 상태가 누적됩니다.

LangGraph는 이 상태 변화 과정을 명확하고 안전하게 표현할 수 있도록

다음의 요소로 구성됩니다:

  • State (현재 기억 / 맥락)
  • Node (행동 단위)
  • Edge (Node 간의 흐름 제어)
  • Reducer (상태를 갱신하는 규칙)

🧱 1. State — 에이전트의 “현재 기억”

State는 에이전트가 지금까지 얻은 정보, 맥락, 중간 산출물이 저장되는 공간입니다.

즉, 에이전트가 어떤 상황에 있는지를 표현하는 작업 기억(Working Memory) 입니다.

LangGraph에서는 State를 표현할 때 두 가지 방식을 사용합니다.

(1) TypedDict 기반 State

from typing import TypedDict, Annotated
from langgraph.graph import add_messages

class State(TypedDict):
    messages: Annotated[list, add_messages]

  • 가벼움, 단순함
  • Python 타입 기반
  • 빠르게 프로토타이핑할 때 유용

(2) Pydantic BaseModel 기반 State

from pydantic import BaseModel, Field
from typing import List

class State(BaseModel):
    messages: List[str] = Field(default_factory=list)

  • 검증(Validation) + 형식 보장
  • API 연동, DB 저장 등 실전 환경에 더 적합

비교 항목 TypedDict Pydantic

사용 목적 빠른 시제품 실무, 안정성
타입 검사 느슨함 엄격함
유효성 검증 없음 자동 검증
권장 시점 학습·실험 단계 제품 단계

정리하자면, 학습 중에는 TypedDict,

실무 적용 단계에서는 Pydantic이 보다 안전합니다.


Reducer — 상태를 어떻게 갱신할 것인가?

State는 매 Node 실행 시마다 새로 교체되는 것이 아니라,

각 Node가 반환한 delta(변경점) 을 기존 상태에 병합(merge) 합니다.

이 병합 규칙을 정하는 것이 Reducer입니다.

예를 들어, messages 라는 상태를 누적하고 싶다면:

messages: Annotated[list, add_messages]

add_messages Reducer는:

기존 리스트 + 새 리스트 → 하나의 리스트로 누적

라는 의미입니다. 일종의 파이썬에서의 extend() 함수 역할이죠!

Reducer 동작 사용 상황

add_messages 리스트에 계속 추가 대화 내용 / reasoning 로그
operator.or_ 딕셔너리 병합 정보 업데이트
operator.add 숫자 / 리스트 덧셈 카운팅 상태

Reducer 덕분에 에이전트는 “기억을 잃지 않고 사고를 이어갈 수 있습니다.”


🔨 Node — 에이전트의 행동 단위

Node는 State를 입력받아, State의 일부를 갱신하는 함수입니다.

def think(state: State):
    result = llm.invoke(state["messages"])
    return {"messages": [result]}

  • Node 하나 = 에이전트의 한 단계 행동
  • 예: 요약하기, 검색하기, 판단하기, 정답 생성하기 등

🔗 3. Edge — Node 간 실행 흐름 제어

Edges는 "어떤 Node 다음에 어떤 Node가 실행되는가" 를 결정합니다.

Edge 유형 설명 예시

순차 Edge A → B 기본 흐름
조건 Edge A → (조건) → B or C 분기 / 종료 결정

LangGraph의 강점은 Loop(순환) 표현이 자연스럽다는 점입니다.

graph.add_edge("think", "think")  # 반복 사고

이런 구조는 Plan → Act → Reflect 같은 에이전트 동작에 매우 적합합니다.


핵심 요약

요소 역할 비유

State 에이전트의 현재 기억 수첩 📒
Reducer 기억을 어떻게 쌓는가 필기 방식 🖊️
Node 단계별 행동 생각 또는 작업 🤔
Edge 다음 행동 결정 흐름 제어 → 루프 🔁

에이전트란, 기억(State)을 기반으로 행동(Node)을 수행하고, 그 결과를 계속 축적(Reducer)하며, 상황에 따라 흐름(Edge)을 조절하는 시스템입니다.

LangGraph는 이 과정을 안전하고 직관적으로 설계할 수 있도록 도와줍니다.

728x90
반응형
728x90
반응형

첫날은 코드보다 개념에 집중해, AI Agent의 발전 과정과 흐름을 정리해보고자 한다.


1. AI Agent, 왜 주목받고 있을까?

최근 AI의 화두는 더 이상 “모델의 성능”이 아니다.

LLM을 어떻게 ‘에이전트’로 발전시킬 수 있는가가 새로운 주제다.

ChatGPT, Claude, Gemini 같은 LLM은 매우 강력하지만,

여전히 “한 번의 프롬프트 → 한 번의 응답”이라는

정적(Static) 구조에 머물러 있다.

💬 에이전트란?

단순히 답을 생성하는 모델이 아니라,

상태(state) 를 유지하며 목표(goal) 를 향해

스스로 계획(plan) 하고 행동(act) 하며 반성(reflect) 하는 시스템이다.


2. 에이전트의 발전 단계

AI의 진화는 “모델 중심”에서 “시스템 중심”으로 옮겨가는 과정이었다.

 

단계 시대 핵심 개념 특징
1단계: 규칙 기반 시스템 1980s~1990s Expert System 사람이 만든 규칙에 따라 작동. 유연성 부족
2단계: Task-specific 모델 2010s 딥러닝 기반 번역, 이미지 분류 등 단일 작업에 특화
3단계: LLM 기반 어시스턴트 2020~2022 ChatGPT, Claude 대화형 모델로 발전, 자연스러운 상호작용 가능
4단계: Agentic Architecture 2023~현재 ReAct, AutoGPT, LangGraph 계획·행동·기억을 통합한 자율 시스템

3. CoT → ReAct → AI Agent로의 진화

LLM이 지금처럼 사고하고 행동하는 존재로 발전하기까지, 세 가지 중요한 흐름이 있었다.

흥미롭게도, 이 모든 것은 ‘프롬프트 엔지니어링’ 에서 출발했다.


3.1 CoT (Chain of Thought)

  • 출발점: 2022년 Google 논문
  • “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models”
  • 핵심 아이디어:즉, 사고 과정을 언어로 표현하게 하는 프롬프트 기법이었다.
  • Q: 3명의 학생이 각각 2개의 사과를 가지고 있다면, 총 몇 개인가? A: 학생 한 명당 2개 → 3 × 2 = 6 → 정답은 6.
  • 모델에게 “정답만 말하지 말고, 생각의 과정을 단계적으로 써라.”
  • 성과:모델의 논리적 정확도가 눈에 띄게 향상되었다.
  • 단순한 지시 한 줄(“Let’s think step by step”)만으로
  • 한계:
  • CoT는 ‘생각’을 시각화했을 뿐, 행동(Action) 이나 기억(Memory) 은 여전히 불가능했다.

3.2 ReAct (Reason + Act)

  • 출발점: 2022년 스탠퍼드 논문
  • “ReAct: Synergizing Reasoning and Acting in Language Models”
  • 핵심 아이디어:프롬프트를 설계하면, 외부 도구를 사용할 수 있다.
  • Thought: 날씨를 알아보기 위해 검색해야겠다. Action: search("오늘 서울 날씨") Observation: 25도 맑음 Thought: 맑은 날씨군. 외출하기 좋겠다. Answer: 오늘 서울은 맑고 25도입니다.
  • LLM이 “생각(Reasoning)”과 “행동(Action)”을 번갈아 수행하도록
  • 프롬프트의 역할:
  • 모델이 스스로 툴을 사용하는 것처럼 보이게 하는 템플릿이었다.
  • 의의:
  • 단순 추론(CoT)을 넘어 “환경과 상호작용하는 모델” 로 진화.
  • 한계:
  • 세션 단위에서만 작동하며, 상태(State)나 메모리(Memory)가 없어 지속적 맥락 유지가 불가능했다.

3.3 AI Agent (Agentic Architecture)

  • 기원: CoT와 ReAct의 프롬프트 패턴을 시스템 수준으로 확장.그 과정을 State(상태) 로 관리할 수 있지 않을까?”
  • → 이 질문이 Agent 아키텍처의 출발점이었다.
  • “모델이 reasoning과 acting을 반복한다면,
  • 핵심 아이디어:Plan → Act → Reflect → Repeat 의 루프를
  • 구조적으로 설계하고 관리하는 시스템.
  • 단일 호출이 아닌,
  • 대표 구현체:
    • AutoGPT / BabyAGI – 자율적 목표 설정 및 하위 작업 수행
    • LangChain AgentExecutor – 도구 기반 행동 흐름
    • LangGraph – 상태(State) 기반 그래프 아키텍처

🚀 정리하자면:

CoT와 ReAct는 “프롬프트 수준의 패턴”이었고,

LangGraph 기반 AI Agent는 그 철학을 “시스템 수준의 아키텍처” 로 확장한 결과물이다.


4. 현대 에이전트의 구성 요소

구성 요소 설명 LangGraph에서의 대응
State Agent의 현재 상태, 메모리, 맥락을 저장 TypedDict, Pydantic 기반 정의
Node 단일 작업 단위 (예: 검색, 요약, 판단 등) 그래프의 각 노드로 구성
Edge 노드 간의 흐름 제어 순차 실행, 조건 분기
Memory 장기 맥락 유지 MemorySaver, Redis, SQLite
Tool 외부 시스템과의 상호작용 Runnable, ToolNode, Function Calling
Workflow 전체 Agent 실행 흐름 StateGraph → compile() 후 실행

LangGraph는 이 모든 요소를 그래프 형태로 시각화하고, 상태 변화와 데이터 흐름을 구조적으로 관리할 수 있게 해준다.


5. 왜 LangGraph인가?

LangGraph는 LangChain 팀에서 개발한 LLM 기반 Agent Workflow Framework 다.

기존 LangChain의 한계를 극복하고, “Stateful AI Agent” 개념을 구조적으로 구현할 수 있게 한다.

💡 LangGraph의 철학:

“LLM은 함수(Function)가 아니라 프로세스(Process)다.”

각 노드(Node)가 상태(State)를 입력받아 결과(delta)를 반환하고, 그래프(Graph)는 이를 병합(merge)하며 하나의 지능적 흐름(Intelligent Flow) 으로 작동한다.


6. Agentic AI의 다음 단계

이제 에이전트는 단순한 도우미가 아니라, 도메인 전문성과 자기 반성 능력(Self-Reflection) 을 가진 자율적 문제 해결 시스템으로 진화하고 있다.

예시:

  • RAG + Planner Agent → 검색 + 의사결정 자동화
  • Tool-use Agent → API 호출, 코드 실행, 문서 생성
  • Memory-based Agent → 장기 대화 및 컨텍스트 유지
  • GraphRAG / Knowledge Agent → 지식 그래프 기반 추론
728x90
반응형
728x90
반응형

안녕하세요! 테디노트님의 RAG 비법노트 37일차 학습 기록입니다.

오늘은 어제(36일차)까지 배운 OpenAI 임베딩을 한 단계 발전시켜, 임베딩을 캐싱(Cache) 하는 방법을 실습했습니다.

RAG 파이프라인에서는 문서를 임베딩할 때마다 모델이 호출되기 때문에, 동일한 데이터를 여러 번 처리하면 비용과 시간이 낭비됩니다.

이를 해결하는 방법이 바로 CacheBackedEmbeddings 입니다.


1. CacheBackedEmbeddings란?

CacheBackedEmbeddings는 임베딩 결과를 저장해두었다가

같은 텍스트를 다시 임베딩할 때 모델을 재호출하지 않고 캐시된 결과를 사용하는 래퍼(wrapper) 클래스입니다.

즉, “이미 계산된 임베딩은 다시 계산하지 않는다”는 개념입니다.

이 방식은 특히 대량 문서 처리나 벡터 DB 구축 시 큰 효율을 가져옵니다.


2. 작동 원리

  • 텍스트를 해시(hash)하여 캐시의 Key로 사용
  • 해시된 Key와 임베딩 벡터를 Key-Value 저장소(ByteStore) 형태로 저장
  • 다음에 같은 텍스트를 요청하면 → 모델 호출 대신 캐시에서 즉시 반환

핵심 초기화 함수는 다음과 같습니다. 👇

CacheBackedEmbeddings.from_bytes_store(
    underlying_embeddings,        # 실제 임베딩 모델 (예: OpenAIEmbeddings)
    document_embedding_cache,     # 캐시 저장소 (LocalFileStore, InMemoryByteStore 등)
    namespace=embedding.model     # 네임스페이스(중복 방지용)
)

💡 주의

다른 임베딩 모델을 동시에 쓸 때 충돌이 날 수 있으므로

namespace에는 보통 모델 이름(embedding.model)을 넣습니다.


3. LocalFileStore로 임베딩 캐싱 (영구 저장)

먼저, 로컬 디스크에 캐시를 저장하는 방식입니다.

한 번 생성된 임베딩은 ./cache/ 폴더에 저장되어, 다음 실행 시 재활용됩니다.

from langchain.storage import LocalFileStore
from langchain_openai import OpenAIEmbeddings
from langchain.embeddings import CacheBackedEmbeddings
from langchain_community.vectorstores.faiss import FAISS

# 1. 기본 임베딩 설정
embedding = OpenAIEmbeddings(model="text-embedding-3-small")

# 2. 로컬 저장소 설정
store = LocalFileStore("./cache/")

# 3. 캐시 지원 임베딩 객체 생성
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
    underlying_embeddings=embedding,
    document_embedding_cache=store,
    namespace=embedding.model
)

# 4. 캐시 키 확인
list(store.yield_keys())

 

이제 문서를 로드하고 분할한 뒤, FAISS 벡터 저장소를 생성해봅니다.

from langchain.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter

# 문서 로드 및 분할
raw_documents = TextLoader("./data/appendix-keywords.txt").load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = text_splitter.split_documents(raw_documents)

# 첫 번째 실행 (임베딩 계산 포함)
%time db = FAISS.from_documents(documents, cached_embedder)

# 두 번째 실행 (캐시 활용, 훨씬 빠름)
%time db2 = FAISS.from_documents(documents, cached_embedder)

 

실행 결과 비교 예시

첫 번째 실행: CPU times: user 100 ms, sys: 19.3 ms, total: 120 ms
Wall time: 1.32 s
두 번째 실행: CPU times: user 4.61 ms, sys: 2.18 ms, total: 6.79 ms
Wall time: 6.96 ms

📈 캐싱 덕분에 속도는 수십 배 빨라지고,

비용(OpenAI API 호출 수) 또한 크게 절감됩니다.


4. InMemoryByteStore로 임베딩 캐싱 (비영구 저장)

이번엔 메모리 기반 캐시를 사용해봅시다.

이 방식은 실행 중에만 데이터를 유지하며, 프로그램 종료 시 사라집니다.

from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import InMemoryByteStore
from langchain_openai import OpenAIEmbeddings

embedding = OpenAIEmbeddings(model="text-embedding-3-small")
store = InMemoryByteStore()

cached_embedder = CacheBackedEmbeddings.from_bytes_store(
    embedding, store, namespace=embedding.model
)

💡 InMemoryByteStore

  • 장점: 빠름, 임시 테스트용으로 적합
  • 단점: 프로그램 종료 시 데이터 손실 (디스크 저장 아님)

 

Local vs InMemory 비교

구분 클래스 저장 위치  영구성 사용예시
LocalFileStore langchain.storage.LocalFileStore 로컬 디스크(./cache/) ✅ 영구 RAG 서비스 구축 시
InMemoryByteStore langchain.storage.InMemoryByteStore 메모리 내 ❌ 비영구 실험, 테스트 환경

🧾 마무리

오늘은 CacheBackedEmbeddings를 활용하여 임베딩을 효율적으로 캐싱하는 방법을 학습했습니다.

💬 한 줄 요약

RAG의 성능을 높이는 가장 쉬운 최적화는 “이미 계산된 임베딩을 다시 계산하지 않는 것”이다.

 

읽어주셔서 감사합니다!

728x90
반응형
728x90
반응형

오늘부터 6주간 진행되는 (사실은 조금 먼저 시작된) 에이전트 스터디에 참여하게 되었다.

이번 스터디는 단순히 LangChain이나 LLM 툴킷을 사용하는 수준을 넘어,

LangGraph를 활용해 에이전트의 동작 원리와 구조를 직접 설계하고 구현하는 것을 목표로 한다.

특히,

  • 에이전트의 상태(State)흐름(Workflow) 을 명확히 이해하고,
  • Tool-Use / Planner-Executor / Memory 구조를 직접 구성해보며,
  • 실무 도메인에 맞는 Agentic Workflow 를 완성하는 것이 이번 스터디의 핵심이다.

🧭 스터디 진행 방식

매주 한 가지 핵심 주제를 중심으로 이론 발표 + 실습 + 토론이 진행된다.

매 회차는 주 발표자(25분+)부 발표자(10분+) 로 구성되며,

모든 팀원이 Notion에 개인 페이지를 만들어 학습 내용을 정리하고,

GitHub에는 실습 코드를 함께 공유한다.

🕐 진행 규칙 요약

  • 무단 2회 결석 시 제명 (책임감 있는 운영)
  • 매주 2인 발표 (이론 + 실습)
  • 세션은 약 70분 (발표 40분 + 토론 20분)
  • 발표자가 아니더라도 자유롭게 정리 및 공유 가능

🗓️ 커리큘럼 요약

주차 학습 주제 핵심 키워드

1주차 Agent 기본 아키텍처, LangGraph 시작 State · Node · Edge · Workflow
2주차 RAG 구조 및 리트리버 설계 Chunking · Embedding · Retriever · Reranker
3주차 Planner & Executor, Reflexion Plan-and-Execute · 논리적 플로우 설계
4주차 Tool-Use & Function Calling Function · Runnable · GraphState
5주차 MCP (Model Context Protocol) Context Sharing · Function Abstraction
6주차 State & Memory 확장 장기 기억 · Context 관리
추가 주제 GraphRAG / Evaluation & Guardrail 지식 그래프 + 안전성 평가

🔭 앞으로의 계획

  • 매주 학습 내용을 정리해 블로그에 기록
  • LangGraph의 핵심 개념(State, Reducer, Message 등)을 직접 코드로 실습
  • 실무 환경에서 재사용 가능한 Agent Template 설계
  • 마지막 주에는 결과물 공유 및 데모 진행

📚 참고 자료


✨ 마무리 다짐

이번 스터디를 통해 단순히 “에이전트를 돌리는 법”이 아니라,

“에이전트가 왜 그렇게 동작하는가”

를 이해하는 수준까지 도달하고 싶다.

LangGraph의 핵심 철학인 “Stateful AI Workflow” 를 제대로 체득하고,

6주 후에는 실무에서 바로 쓸 수 있는 도메인 특화 에이전트를 완성하는 것이 목표다.

728x90
반응형

+ Recent posts