<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko-KR"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mengro1102.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mengro1102.github.io/" rel="alternate" type="text/html" hreflang="ko-KR" /><updated>2026-09-11T10:32:49+09:00</updated><id>https://mengro1102.github.io/feed.xml</id><title type="html">이명로의 Deep Dive</title><subtitle>LLM, SLM, Transformer 등 최신 AI 기술의 원리를 깊이 있게 파헤치고, 효율적인 최적화 및 구현 방법을 탐구하는 기술 블로그입니다.</subtitle><entry><title type="html">AI 에이전트 아키텍처 4대 패턴: ReAct, Plan-Execute, Reflexion, Multi-Agent</title><link href="https://mengro1102.github.io/posts/2026/05/07/ai-agent-architecture-patterns/" rel="alternate" type="text/html" title="AI 에이전트 아키텍처 4대 패턴: ReAct, Plan-Execute, Reflexion, Multi-Agent" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/ai-agent-architecture-patterns</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/ai-agent-architecture-patterns/"><![CDATA[<p>2025~2026년, AI 에이전트는 “챗봇”에서 “자율적 행위자”로 진화했다. Claude Code가 코드를 작성하고, Cursor가 프로젝트를 리팩토링하며, AutoResearchClaw가 논문을 쓴다.</p>

<p>하지만 이 에이전트들의 내부를 들여다보면, 몇 가지 반복되는 아키텍처 패턴이 보인다. 이 글은 그 패턴들을 정리하고, 각각의 트레이드오프를 분석한다.</p>

<hr />

<h2 id="1-에이전트의-핵심-루프">1. 에이전트의 핵심 루프</h2>

<p>모든 AI 에이전트는 하나의 루프로 귀결된다:</p>

<div class="mermaid">
graph LR
    A[입력] --&gt; B[추론/계획]
    B --&gt; C[도구 호출]
    C --&gt; D[행동]
    D --&gt; E[관찰]
    E --&gt; F[평가]
    F --&gt; G[정제]
    G --&gt; B
</div>

<p>차이는 이 루프를 <strong>어떻게 구조화하느냐</strong>에 있다.</p>

<hr />

<h2 id="2-4대-아키텍처-패턴">2. 4대 아키텍처 패턴</h2>

<h3 id="21-react-reason--act">2.1. ReAct (Reason + Act)</h3>

<p>가장 기본적이고 널리 쓰이는 패턴. 추론(Thought)과 행동(Action)을 교대로 수행한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Thought: 사용자가 버그를 보고했다. 먼저 에러 로그를 확인해야 한다.
Action: read_file("error.log")
Observation: TypeError: Cannot read property 'name' of undefined
Thought: user 객체가 undefined인 경우가 있다. null check를 추가해야 한다.
Action: edit_file("user.js", ...)
Observation: 파일 수정 완료
Thought: 테스트를 실행하여 수정을 검증한다.
Action: run_command("npm test")
Observation: All tests passed
Answer: 버그를 수정했습니다. user 객체의 null check를 추가했습니다.
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>장점</th>
      <th>단점</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>단순하고 직관적</td>
      <td>매 단계 LLM 호출 → 비용/지연</td>
    </tr>
    <tr>
      <td>투명한 추론 과정</td>
      <td>루프에 빠질 위험</td>
    </tr>
    <tr>
      <td>동적 환경 적응</td>
      <td>장기 계획 능력 부족</td>
    </tr>
  </tbody>
</table>

<p><strong>사용 사례</strong>: Claude Code, OpenHarness, 대부분의 코딩 에이전트</p>

<h3 id="22-plan-and-execute-계획-실행-분리">2.2. Plan-and-Execute (계획-실행 분리)</h3>

<p>전략적 계획과 전술적 실행을 분리한다. Planner가 한 번 계획을 세우고, Executor가 순차 실행한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Planner]
1. 프로젝트 구조 분석
2. 관련 파일 식별
3. 수정 코드 작성
4. 테스트 실행
5. PR 생성

[Executor]
Step 1: list_directory("src/") → 구조 파악
Step 2: read_file("src/auth.js") → 관련 파일 확인
Step 3: edit_file("src/auth.js", ...) → 수정
Step 4: run_command("npm test") → 검증
Step 5: create_pr(...) → PR 생성

[Re-planner] (Step 4 실패 시)
수정된 계획: 3번으로 돌아가 edge case 처리 추가
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>장점</th>
      <th>단점</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>복잡한 태스크 분해</td>
      <td>초기 계획 오류 시 전체 실패</td>
    </tr>
    <tr>
      <td>계획 1회 → 실행 N회 (효율적)</td>
      <td>동적 환경 적응 어려움</td>
    </tr>
    <tr>
      <td>진행 상황 추적 용이</td>
      <td>Re-planning 비용</td>
    </tr>
  </tbody>
</table>

<p><strong>사용 사례</strong>: Cursor (복잡한 리팩토링), 연구 에이전트</p>

<h3 id="23-reflexion-자기-반성">2.3. Reflexion (자기 반성)</h3>

<p>실패에서 학습하는 패턴. 시도 → 평가 → 반성 → 재시도 루프를 반복한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[시도 1]
코드 작성 → 테스트 실행 → 3개 실패

[반성]
"edge case를 고려하지 않았다. 빈 배열과 null 입력을 처리해야 한다."

[시도 2]
edge case 추가 → 테스트 실행 → 1개 실패

[반성]
"비동기 처리에서 race condition이 발생한다. await를 추가해야 한다."

[시도 3]
await 추가 → 테스트 실행 → 전체 통과 ✓
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>장점</th>
      <th>단점</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>실패에서 학습</td>
      <td>여러 번 시도 → 비용 증가</td>
    </tr>
    <tr>
      <td>점진적 품질 향상</td>
      <td>반성 품질이 LLM 능력에 의존</td>
    </tr>
    <tr>
      <td>복잡한 문제 해결</td>
      <td>수렴 보장 없음</td>
    </tr>
  </tbody>
</table>

<p><strong>사용 사례</strong>: 코드 생성, 수학 문제 풀이, 복잡한 추론</p>

<h3 id="24-multi-agent-다중-에이전트">2.4. Multi-Agent (다중 에이전트)</h3>

<p>여러 전문화된 에이전트가 협업하는 패턴.</p>

<div class="mermaid">
graph TD
    O[Orchestrator] --&gt; R[Researcher]
    O --&gt; C[Coder]
    O --&gt; V[Reviewer]
    O --&gt; T[Tester]
    R --&gt;|분석 결과| C
    C --&gt;|구현 완료| V
    V --&gt;|피드백| C
    C --&gt;|수정 완료| T
    T --&gt;|통과| O
</div>

<p><strong>실행 흐름 예시:</strong></p>
<ol>
  <li>Orchestrator: “새 API 엔드포인트를 추가해야 합니다”</li>
  <li>Researcher: 기존 API 패턴 분석 결과 전달</li>
  <li>Coder: 패턴에 맞춰 구현</li>
  <li>Reviewer: “에러 핸들링이 부족합니다” → Coder에게 반환</li>
  <li>Coder: 수정 후 Tester에게 전달</li>
  <li>Tester: 테스트 통과 확인 → Orchestrator에 완료 보고</li>
</ol>

<table>
  <thead>
    <tr>
      <th>장점</th>
      <th>단점</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>전문화로 품질 향상</td>
      <td>오케스트레이션 복잡도</td>
    </tr>
    <tr>
      <td>병렬 처리 가능</td>
      <td>에이전트 간 통신 비용</td>
    </tr>
    <tr>
      <td>역할 분리로 디버깅 용이</td>
      <td>설계/구현 난이도 높음</td>
    </tr>
  </tbody>
</table>

<p><strong>사용 사례</strong>: MiroFish (집단 지능), 대규모 프로젝트, 연구 자동화</p>

<hr />

<h2 id="3-메모리-전략-에이전트의-기억">3. 메모리 전략: 에이전트의 기억</h2>

<p>에이전트가 “맥락을 잃지 않는 것”은 핵심 과제다.</p>

<table>
  <thead>
    <tr>
      <th>전략</th>
      <th>방식</th>
      <th>용량</th>
      <th>속도</th>
      <th>적합 상황</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Context Window</td>
      <td>대화 이력을 프롬프트에 포함</td>
      <td>제한적 (128K)</td>
      <td>즉시</td>
      <td>단기 태스크</td>
    </tr>
    <tr>
      <td>RAG</td>
      <td>벡터 DB에서 검색</td>
      <td>무제한</td>
      <td>검색 지연</td>
      <td>대규모 지식</td>
    </tr>
    <tr>
      <td>Wiki (LLM Wiki)</td>
      <td>구조화된 마크다운</td>
      <td>무제한</td>
      <td>파일 읽기</td>
      <td>복리 축적형</td>
    </tr>
    <tr>
      <td>프롬프트 캐싱</td>
      <td>이전 KV Cache 재사용</td>
      <td>세션 내</td>
      <td>매우 빠름</td>
      <td>장기 실행</td>
    </tr>
  </tbody>
</table>

<h3 id="claude-code의-선택-프롬프트-캐싱">Claude Code의 선택: 프롬프트 캐싱</h3>

<p>Claude Code는 전체 아키텍처를 <strong>프롬프트 캐싱</strong> 중심으로 설계했다. 이전 라운드트립의 KV Cache를 재사용하여:</p>
<ul>
  <li>중복 연산 제거</li>
  <li>지연 시간 대폭 감소</li>
  <li>장기 실행 에이전트의 비용 절감</li>
</ul>

<h3 id="hermes-agent의-선택-세션-간-메모리">Hermes Agent의 선택: 세션 간 메모리</h3>

<p>Hermes Agent는 <strong>외부 메모리</strong>에 세션 간 맥락을 저장한다. 어제의 대화를 오늘 이어갈 수 있다.</p>

<hr />

<h2 id="4-도구-연결-mcp의-부상">4. 도구 연결: MCP의 부상</h2>

<p>에이전트가 도구를 호출하는 방식도 표준화되고 있다.</p>

<h3 id="function-calling-openai-스타일">Function Calling (OpenAI 스타일)</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"read_file"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"parameters"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"src/main.py"</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>모델이 JSON 형태로 도구 호출을 생성. 간단하지만 도구 정의가 모델별로 다름.</p>

<h3 id="mcp-model-context-protocol">MCP (Model Context Protocol)</h3>

<p>Anthropic이 주도하는 표준 프로토콜. 도구를 <strong>서버</strong>로 분리하여:</p>
<ul>
  <li>모델 독립적 (어떤 LLM이든 연결 가능)</li>
  <li>도구 재사용 (한 번 만들면 여러 에이전트에서 사용)</li>
  <li>표준화된 인터페이스</li>
</ul>

<div class="mermaid">
graph LR
    A[에이전트] &lt;--&gt;|요청/응답| B[MCP 클라이언트]
    B &lt;--&gt;|표준 프로토콜| C[MCP 서버 - 도구]
</div>

<hr />

<h2 id="5-실제-프레임워크-비교">5. 실제 프레임워크 비교</h2>

<table>
  <thead>
    <tr>
      <th>프레임워크</th>
      <th>패턴</th>
      <th>메모리</th>
      <th>도구 연결</th>
      <th>특징</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Claude Code</td>
      <td>ReAct + 캐싱</td>
      <td>프롬프트 캐싱</td>
      <td>MCP</td>
      <td>캐싱 중심 설계</td>
    </tr>
    <tr>
      <td>Cursor</td>
      <td>Plan-Execute</td>
      <td>Context Window</td>
      <td>내장</td>
      <td>IDE 통합</td>
    </tr>
    <tr>
      <td>OpenHarness</td>
      <td>ReAct</td>
      <td>Context Window</td>
      <td>Function Call</td>
      <td>44배 경량</td>
    </tr>
    <tr>
      <td>Hermes Agent</td>
      <td>ReAct + 메모리</td>
      <td>외부 메모리</td>
      <td>플러그인</td>
      <td>세션 간 맥락</td>
    </tr>
    <tr>
      <td>AutoResearchClaw</td>
      <td>Plan-Execute</td>
      <td>RAG</td>
      <td>다중 도구</td>
      <td>연구 자동화</td>
    </tr>
    <tr>
      <td>MiroFish</td>
      <td>Multi-Agent</td>
      <td>공유 상태</td>
      <td>CAMEL-AI</td>
      <td>집단 지능</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="6-패턴-선택-가이드">6. 패턴 선택 가이드</h2>

<div class="mermaid">
graph TD
    Q{태스크 복잡도?}
    Q --&gt;|단순 1~3단계| R[ReAct]
    Q --&gt;|복잡 4+단계| C{세부 조건?}
    C --&gt;|실패에서 학습| RF[Reflexion]
    C --&gt;|병렬 처리 가능| MA[Multi-Agent]
    C --&gt;|순차적 실행| PE[Plan-and-Execute]
</div>

<p>실무에서의 경험칙:</p>
<ul>
  <li><strong>대부분의 코딩 태스크</strong>: ReAct로 충분</li>
  <li><strong>대규모 리팩토링</strong>: Plan-and-Execute</li>
  <li><strong>품질이 중요한 생성</strong>: Reflexion</li>
  <li><strong>연구/분석</strong>: Multi-Agent 또는 Plan-and-Execute</li>
</ul>

<hr />

<h2 id="7-미래-방향">7. 미래 방향</h2>

<h3 id="에이전트의-에이전트-meta-agent">에이전트의 에이전트 (Meta-Agent)</h3>

<p>태스크에 따라 최적 패턴을 자동 선택하는 메타 에이전트. “이 태스크는 Plan-Execute가 적합하다”를 스스로 판단.</p>

<h3 id="학습하는-에이전트">학습하는 에이전트</h3>

<p>Reflexion을 넘어, 과거 경험에서 패턴을 학습하여 점점 효율적으로 동작하는 에이전트. DiscoRL의 메타러닝 아이디어와 연결.</p>

<h3 id="표준화">표준화</h3>

<p>MCP의 확산으로 도구 생태계가 표준화되면, 에이전트 간 도구 공유와 협업이 자연스러워진다.</p>

<hr />

<h2 id="정리">정리</h2>

<p>AI 에이전트의 핵심은 “어떤 패턴으로 루프를 구조화하느냐”다.</p>

<table>
  <thead>
    <tr>
      <th>패턴</th>
      <th>핵심 아이디어</th>
      <th>비용</th>
      <th>품질</th>
      <th>복잡도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>ReAct</td>
      <td>추론-행동 교대</td>
      <td>중간</td>
      <td>기준</td>
      <td>낮음</td>
    </tr>
    <tr>
      <td>Plan-Execute</td>
      <td>계획-실행 분리</td>
      <td>낮음</td>
      <td>좋음</td>
      <td>중간</td>
    </tr>
    <tr>
      <td>Reflexion</td>
      <td>실패에서 학습</td>
      <td>높음</td>
      <td>높음</td>
      <td>중간</td>
    </tr>
    <tr>
      <td>Multi-Agent</td>
      <td>전문화 협업</td>
      <td>높음</td>
      <td>높음</td>
      <td>높음</td>
    </tr>
  </tbody>
</table>

<p>2026년의 에이전트는 아직 초기 단계다. 하지만 패턴이 수렴하고 있고, MCP 같은 표준이 자리잡으면서, “에이전트를 설계하는 것”이 “프로그램을 작성하는 것”만큼 체계적인 엔지니어링이 되어가고 있다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/mcp/">MCP (Model Context Protocol)</a></li>
  <li><a href="/concepts/rag/">RAG (Retrieval-Augmented Generation)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Masterman et al., “The Landscape of Emerging AI Agent Architectures for Reasoning, Planning, and Tool Calling” (2024), <a href="https://arxiv.org/abs/2404.11584">arXiv:2404.11584</a></li>
  <li>Anthropic, “Claude Code: Lessons from Building” (2026)</li>
  <li>NeuralWired, “Multi-Agent Orchestration Patterns Drive Enterprise ROI” (2026)</li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="Agent" /><category term="AI에이전트" /><category term="ReAct" /><category term="MCP" /><category term="LLM" /><category term="아키텍처" /><summary type="html"><![CDATA[2026년 AI 에이전트의 4대 아키텍처 패턴을 비교하고, 메모리 전략과 도구 연결 프로토콜, 그리고 실제 프레임워크들의 설계 철학을 분석한다.]]></summary></entry><entry><title type="html">DiscoRL: 메타러닝으로 강화학습 알고리즘을 자동 발견하다</title><link href="https://mengro1102.github.io/posts/2026/05/07/discorl-meta-learning-rl/" rel="alternate" type="text/html" title="DiscoRL: 메타러닝으로 강화학습 알고리즘을 자동 발견하다" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/discorl-meta-learning-rl</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/discorl-meta-learning-rl/"><![CDATA[<p>2025년 10월, Nature에 한 편의 논문이 게재되었다. “Discovering state-of-the-art reinforcement learning algorithms.” 저자 목록의 첫 번째 이름은 Junhyuk Oh — 내가 롤모델로 삼고 있는 연구자다.</p>

<p>이 논문의 핵심 주장은 도발적이다: <strong>기계가 스스로 SOTA 강화학습 알고리즘을 발견할 수 있다.</strong> 그리고 그 발견된 규칙(DiscoRL)은 인간이 수십 년간 설계해온 모든 알고리즘을 능가한다.</p>

<hr />

<h2 id="1-왜-이-논문이-중요한가">1. 왜 이 논문이 중요한가</h2>

<p>인간의 학습 메커니즘은 수백만 년의 생물학적 진화가 발견한 것이다. 반면 인공 에이전트의 학습 규칙(Q-Learning, PPO, MuZero 등)은 연구자가 수동으로 설계한다. 이 과정은:</p>

<ul>
  <li>느리고 (수년의 연구 기간)</li>
  <li>인간의 직관에 의존하며 (탐색 공간이 제한됨)</li>
  <li>발견 가능한 알고리즘의 범위가 좁다</li>
</ul>

<p>DiscoRL은 이 패러다임을 뒤집는다: <strong>학습 규칙 자체를 학습한다.</strong></p>

<hr />

<h2 id="2-핵심-아이디어-2단계-최적화">2. 핵심 아이디어: 2단계 최적화</h2>

<h3 id="일반-rl-vs-discorl">일반 RL vs DiscoRL</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>일반 RL:
  고정된 규칙(예: PPO)으로 에이전트를 학습

DiscoRL:
  외부 루프: 규칙 자체를 최적화 (메타러닝)
    내부 루프: 그 규칙으로 에이전트를 학습
</code></pre></div></div>

<p>외부 루프(느린 메타학습)가 내부 루프(빠른 에이전트 학습)를 최적화한다. 마치 진화가 학습 메커니즘을 발견하듯이.</p>

<hr />

<h2 id="3-방법론-상세">3. 방법론 상세</h2>

<h3 id="31-agent-network-무엇을-예측하는가">3.1. Agent Network: 무엇을 예측하는가</h3>

<p>에이전트는 5가지 출력을 생성한다:</p>

<table>
  <thead>
    <tr>
      <th>출력</th>
      <th>의미</th>
      <th>특징</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>π</td>
      <td>정책 (행동 확률)</td>
      <td>표준</td>
    </tr>
    <tr>
      <td>y(s) ∈ ℝⁿ</td>
      <td>관측 조건부 예측</td>
      <td><strong>의미 자동 발견</strong></td>
    </tr>
    <tr>
      <td>z(s,a) ∈ ℝᵐ</td>
      <td>행동 조건부 예측</td>
      <td><strong>의미 자동 발견</strong></td>
    </tr>
    <tr>
      <td>q(s,a)</td>
      <td>행동 가치 함수</td>
      <td>사전 정의</td>
    </tr>
    <tr>
      <td>p(s,a)</td>
      <td>보조 정책 예측</td>
      <td>사전 정의</td>
    </tr>
  </tbody>
</table>

<p>핵심: <strong>y와 z의 의미(semantics)는 사전에 정의되지 않는다.</strong> “가치 함수가 되어라”라고 지정하지 않는다. 메타네트워크가 학습 과정에서 이 예측들이 무엇을 의미해야 하는지를 스스로 결정한다.</p>

<p>이 설계의 근거: RL의 근본적 구분인 “예측(prediction)”과 “제어(control)”를 반영. y는 상태 가치 함수 v(s)처럼 관측에만 의존하고, z는 행동 가치 함수 q(s,a)처럼 행동에도 의존한다. 하지만 그 구체적 의미는 열려 있다.</p>

<h3 id="32-meta-network-타겟을-생성하는-lstm">3.2. Meta-Network: 타겟을 생성하는 LSTM</h3>

<p>메타네트워크는 에이전트가 “어디로 향해야 하는지”를 알려주는 타겟을 생성한다:</p>

\[m_\eta: \text{trajectory}(t \to t+n) \mapsto (\hat{\pi}, \hat{y}, \hat{z})\]

<ul>
  <li><strong>입력</strong>: 에이전트 출력의 궤적 + 보상 + 에피소드 종료 신호 (시간 t ~ t+n)</li>
  <li><strong>처리</strong>: LSTM을 시간 역방향으로 unroll</li>
  <li><strong>출력</strong>: 에이전트의 예측과 정책이 향해야 할 타겟</li>
</ul>

<p>왜 역방향인가? n-step 미래 정보를 활용하여 타겟을 구성하기 위해. TD(λ)와 같은 multi-step 방법의 일반화.</p>

<h3 id="33-agent-loss-kl-divergence-기반">3.3. Agent Loss: KL Divergence 기반</h3>

\[L(\theta) = \mathbb{E}_{s,a \sim \pi_\theta} [D_{KL}(\hat{\pi} \| \pi_\theta) + D_{KL}(\hat{y} \| y_\theta) + D_{KL}(\hat{z} \| z_\theta) + L_{aux}]\]

<p>에이전트는 메타네트워크가 제시한 타겟 방향으로 자신의 예측을 업데이트한다. 거리 함수로 KL divergence를 사용.</p>

<h3 id="34-meta-gradient-업데이트-과정을-역전파">3.4. Meta-Gradient: 업데이트 과정을 역전파</h3>

\[\nabla_\eta J(\eta) \approx \mathbb{E}_\mathcal{E} \mathbb{E}_\theta [\nabla_\eta \theta \cdot \nabla_\theta J(\theta)]\]

<ul>
  <li>$\nabla_\eta \theta$: 에이전트 업데이트 과정 전체를 통한 역전파 (20 업데이트 sliding window)</li>
  <li>$\nabla_\theta J(\theta)$: Advantage Actor-Critic으로 추정</li>
</ul>

<p>이것이 계산적으로 가장 비싼 부분이다. 에이전트가 20번 업데이트되는 전체 과정을 미분 가능하게 만들어야 한다.</p>

<hr />

<h2 id="4-실험-결과">4. 실험 결과</h2>

<h3 id="41-atari-57-모든-기존-알고리즘-능가">4.1. Atari 57: 모든 기존 알고리즘 능가</h3>

<p>Disco57 (Atari 57에서 메타학습):</p>
<ul>
  <li><strong>IQM: 13.86</strong> — MuZero, Dreamer, MEME 등 모든 기존 알고리즘 능가</li>
  <li>MuZero 대비 약 <strong>40% 적은 연산량</strong>으로 동일 성능 도달</li>
  <li>발견 시보다 큰 네트워크에서도 일반화</li>
</ul>

<h3 id="42-일반화-본-적-없는-환경에서도-sota">4.2. 일반화: 본 적 없는 환경에서도 SOTA</h3>

<table>
  <thead>
    <tr>
      <th>벤치마크</th>
      <th>환경 수</th>
      <th>DiscoRL 결과</th>
      <th>비교</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>ProcGen</td>
      <td>16 games</td>
      <td><strong>모든 기존 방법 능가</strong></td>
      <td>MuZero, PPO 포함</td>
    </tr>
    <tr>
      <td>Crafter</td>
      <td>1</td>
      <td>인간 수준 (Disco103)</td>
      <td>—</td>
    </tr>
    <tr>
      <td>NetHack</td>
      <td>1</td>
      <td>NeurIPS 2021 Challenge <strong>3위</strong></td>
      <td>도메인 지식 없이</td>
    </tr>
    <tr>
      <td>Sokoban</td>
      <td>1</td>
      <td>MuZero에 근접 (Disco103)</td>
      <td>—</td>
    </tr>
    <tr>
      <td>DMLab-30</td>
      <td>30</td>
      <td>경쟁적</td>
      <td>IMPALA 대비 우수</td>
    </tr>
  </tbody>
</table>

<p>특히 ProcGen 결과가 인상적이다. Disco57은 Atari에서만 메타학습했는데, 전혀 다른 구조의 ProcGen 게임에서도 SOTA를 달성했다. 이는 발견된 규칙이 특정 환경에 과적합된 것이 아니라 <strong>범용적인 학습 원리</strong>를 포착했음을 의미한다.</p>

<h3 id="43-스케일링-환경이-많을수록-강해진다">4.3. 스케일링: 환경이 많을수록 강해진다</h3>

<ul>
  <li>Disco57 (57 환경) → Disco103 (103 환경): 모든 미학습 벤치마크에서 향상</li>
  <li>환경 다양성 ↑ → 발견된 규칙의 일반성 ↑</li>
  <li>단순 환경(grid-world)에서 발견 → Atari에서 성능 저조</li>
</ul>

<p>이것은 “데이터와 컴퓨트의 함수로서의 알고리즘 품질”이라는 스케일링 법칙의 메타러닝 버전이다.</p>

<hr />

<h2 id="5-분석-discorl은-무엇을-발견했는가">5. 분석: DiscoRL은 무엇을 발견했는가</h2>

<h3 id="51-발견된-예측의-의미">5.1. 발견된 예측의 의미</h3>

<p>논문의 가장 흥미로운 부분이다. y와 z는 무엇이 되었는가?</p>

<ul>
  <li><strong>미래 중요 이벤트 직전에 spike</strong>: 보상 획득이나 정책 엔트로피 변화 전에 예측 신뢰도가 급등</li>
  <li><strong>정책/가치함수와 다른 객체에 주목</strong>: Gradient 분석 결과, 정책은 가까운 적에, 가치함수는 점수판에, 발견된 예측은 <strong>먼 거리의 적</strong>에 집중</li>
  <li><strong>고유한 정보 포착</strong>: 미래 엔트로피와 대형 보상 이벤트를 정책이나 가치함수보다 더 잘 예측</li>
</ul>

<p>즉, DiscoRL은 기존 RL에 없던 새로운 종류의 “미래 예측”을 발명한 것이다. 가치 함수가 “미래 보상의 합”을 예측한다면, 발견된 예측은 “미래에 중요한 일이 일어날 것”을 예측한다.</p>

<h3 id="52-부트스트래핑의-자연-출현">5.2. 부트스트래핑의 자연 출현</h3>

<p>부트스트래핑(미래 예측값을 현재 타겟으로 사용)은 TD Learning의 핵심 아이디어다. DiscoRL에서는 이것이 <strong>명시적으로 프로그래밍되지 않았음에도 자연스럽게 출현</strong>했다.</p>

<ul>
  <li>미래 예측 $z_{t+k}$를 교란하면 현재 타겟 $\hat{z}_t$가 크게 변함</li>
  <li>부트스트래핑 제거 시 성능 대폭 하락</li>
  <li>예측이 정책 업데이트에도 직접 활용됨 (단순 보조 태스크가 아님)</li>
</ul>

<p>이는 부트스트래핑이 RL의 “자연법칙”에 가까운 근본적 원리임을 시사한다.</p>

<hr />

<h2 id="6-왜-이전-시도들은-실패했는가">6. 왜 이전 시도들은 실패했는가</h2>

<table>
  <thead>
    <tr>
      <th>이전 연구</th>
      <th>한계</th>
      <th>DiscoRL의 해결</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>하이퍼파라미터 메타러닝</td>
      <td>탐색 공간이 좁음</td>
      <td>예측 의미 + 전체 규칙 발견</td>
    </tr>
    <tr>
      <td>Evolved Policy Gradients</td>
      <td>정책 손실만 발견</td>
      <td>예측·정책·타겟 모두 포함</td>
    </tr>
    <tr>
      <td>RL² (블랙박스)</td>
      <td>메타 과적합</td>
      <td>구조적 귀납 편향 유지</td>
    </tr>
    <tr>
      <td>이전 모든 연구</td>
      <td>단순 환경 (grid-world)</td>
      <td>복잡한 환경 (Atari 57)</td>
    </tr>
  </tbody>
</table>

<p>DiscoRL의 성공 요인 2가지:</p>
<ol>
  <li><strong>넓은 탐색 공간</strong>: 예측의 의미까지 열어둠</li>
  <li><strong>복잡한 환경에서의 대규모 메타학습</strong>: 57~103개의 도전적 환경</li>
</ol>

<hr />

<h2 id="7-시사점과-미래">7. 시사점과 미래</h2>

<h3 id="연구적-시사점">연구적 시사점</h3>

<ul>
  <li>RL 알고리즘 설계가 “인간의 직관”에서 “기계의 발견”으로 전환될 수 있음</li>
  <li>발견된 규칙의 성능이 데이터(환경)와 컴퓨트의 함수 → 스케일링 법칙 적용 가능</li>
  <li>부트스트래핑 같은 근본 원리가 자동으로 재발견됨 → RL 이론의 검증</li>
</ul>

<h3 id="한계">한계</h3>

<ul>
  <li>계산 비용: Disco57 발견에 1,024 TPUv3 × 64시간 (개인 연구자에게는 비현실적)</li>
  <li>연속 행동 공간: 현재는 이산 행동 공간에 집중</li>
  <li>해석 가능성: 발견된 규칙의 완전한 이해는 아직 어려움</li>
</ul>

<h3 id="개인적-의미">개인적 의미</h3>

<p>Junhyuk Oh는 내가 목표로 삼는 연구자다. 이 논문은 그의 연구 궤적에서 하나의 정점이다:</p>
<ul>
  <li>2020 NeurIPS: “Discovering Reinforcement Learning Algorithms” (초기 버전)</li>
  <li>2025 Nature: DiscoRL (대규모 스케일업 + SOTA 달성)</li>
</ul>

<p>5년간의 집요한 추적이 Nature 게재로 결실을 맺었다. “하나의 아이디어를 끝까지 밀어붙이는 것”의 가치를 보여주는 사례.</p>

<hr />

<h2 id="정리">정리</h2>

<p>DiscoRL의 핵심 메시지:</p>

<blockquote>
  <p><strong>RL 알고리즘은 인간이 설계하는 것이 아니라, 기계가 발견하는 것이 될 수 있다.</strong></p>
</blockquote>

<p>그리고 그 발견된 규칙은 인간이 수십 년간 만들어온 모든 것을 능가한다. 이것은 RL 연구의 패러다임 전환이다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/reinforcement-learning/">강화학습 (Reinforcement Learning)</a></li>
  <li><a href="/concepts/meta-learning/">메타러닝 (Meta-Learning)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Oh, J. et al., “Discovering state-of-the-art reinforcement learning algorithms”, Nature (2025), DOI: 10.1038/s41586-025-09761-x</li>
  <li>오픈소스 코드: <a href="https://github.com/google-deepmind/disco_rl">github.com/google-deepmind/disco_rl</a></li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="RL" /><category term="DiscoRL" /><category term="강화학습" /><category term="메타러닝" /><category term="DeepMind" /><category term="Nature" /><summary type="html"><![CDATA[Google DeepMind의 DiscoRL 논문 딥리뷰. 메타네트워크가 RL 업데이트 규칙 자체를 학습하여 Atari 57에서 MuZero를 능가하고, 미학습 환경에도 일반화되는 과정을 분석한다.]]></summary></entry><entry><title type="html">한국어 토큰화의 도전: BPE의 한계와 형태소 인식 접근법</title><link href="https://mengro1102.github.io/posts/2026/05/07/korean-tokenization-bpe/" rel="alternate" type="text/html" title="한국어 토큰화의 도전: BPE의 한계와 형태소 인식 접근법" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/korean-tokenization-bpe</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/korean-tokenization-bpe/"><![CDATA[<p>“안녕하세요”를 GPT-4의 토크나이저에 넣으면 몇 개의 토큰이 나올까? 답은 3~5개. 영어의 “Hello”가 1개 토큰인 것과 비교하면 3~5배 비효율적이다.</p>

<p>이것은 단순한 불편함이 아니다. 토큰 수는 곧 <strong>비용, 속도, 컨텍스트 윈도우 활용률</strong>에 직결된다. 한국어 사용자는 같은 의미를 전달하는 데 더 많은 토큰을 소비하고, 더 많은 비용을 지불하며, 더 짧은 문맥만 활용할 수 있다.</p>

<hr />

<h2 id="1-bpe-복습-왜-표준이-되었는가">1. BPE 복습: 왜 표준이 되었는가</h2>

<p><a href="/concepts/tokenization/">BPE(Byte Pair Encoding)</a>는 원래 텍스트 압축 알고리즘이다. LLM 토큰화에 적용된 핵심 아이디어:</p>

<ol>
  <li>텍스트를 개별 문자(또는 바이트)로 분할</li>
  <li>가장 빈도 높은 인접 쌍을 반복적으로 병합</li>
  <li>목표 어휘 크기에 도달하면 중단</li>
</ol>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"hugs" → 학습 후 → ["hug", "s"]
"unhappiness" → ["un", "happ", "iness"]
</code></pre></div></div>

<p>장점:</p>
<ul>
  <li><strong>OOV 문제 해결</strong>: 어떤 단어든 서브워드 조합으로 표현 가능</li>
  <li><strong>언어 독립적</strong>: 별도의 언어학적 지식 불필요</li>
  <li><strong>단순하고 빠름</strong>: 구현이 간단하고 학습 속도 빠름</li>
</ul>

<p>이 “언어 독립성”이 영어에서는 강점이지만, 한국어에서는 약점이 된다.</p>

<hr />

<h2 id="2-한국어에서-bpe가-실패하는-이유">2. 한국어에서 BPE가 실패하는 이유</h2>

<h3 id="21-교착어의-특성">2.1. 교착어의 특성</h3>

<p>한국어는 <strong>교착어(agglutinative language)</strong>다. 어간에 조사, 어미가 붙어 의미가 변한다:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>먹다 → 먹었다, 먹겠다, 먹었었겠다
학교 → 학교에서, 학교에서부터, 학교에서부터라도
</code></pre></div></div>

<p>BPE는 통계적 빈도만 보므로, 이 형태소 경계를 무시한다:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>BPE 분할: "학교에서" → ["학교에", "서"]  (형태소 경계 무시)
올바른 분할: "학교에서" → ["학교", "에서"]  (어간 + 조사)
</code></pre></div></div>

<h3 id="22-토큰-비효율-높은-fertility">2.2. 토큰 비효율 (높은 Fertility)</h3>

<p><strong>Fertility</strong> = 단어당 평균 토큰 수. 한국어의 fertility는 영어 대비 2~3배 높다.</p>

<table>
  <thead>
    <tr>
      <th>텍스트</th>
      <th>영어 토큰 수</th>
      <th>한국어 토큰 수</th>
      <th>비율</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>“Hello”</td>
      <td>1</td>
      <td>3~5 (“안녕하세요”)</td>
      <td>3~5×</td>
    </tr>
    <tr>
      <td>100단어 문장</td>
      <td>~130 토큰</td>
      <td>~300 토큰</td>
      <td>~2.3×</td>
    </tr>
  </tbody>
</table>

<p>이것이 의미하는 것:</p>
<ul>
  <li><strong>비용 2~3배</strong>: API 과금이 토큰 단위</li>
  <li><strong>속도 2~3배 느림</strong>: 생성 토큰 수에 비례</li>
  <li><strong>컨텍스트 활용률 1/2~1/3</strong>: 같은 128K 윈도우에 담을 수 있는 한국어 텍스트가 적음</li>
</ul>

<h3 id="23-영어-중심-토크나이저의-문제">2.3. 영어 중심 토크나이저의 문제</h3>

<p>GPT-4, Llama 등 영어 중심 모델의 토크나이저는 한국어를 <strong>UTF-8 바이트 단위</strong>로 처리한다. 한글 한 글자가 3바이트이므로, “가”가 3개 토큰이 될 수 있다.</p>

<hr />

<h2 id="3-해결-접근법">3. 해결 접근법</h2>

<h3 id="31-형태소-분석--bpe-하이브리드">3.1. 형태소 분석 + BPE 하이브리드</h3>

<p>가장 검증된 접근법. 형태소 분석으로 언어학적 경계를 먼저 잡고, 그 위에 BPE를 적용한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>원문: "자연어처리를 공부합니다"
→ 형태소 분석: ["자연어", "처리", "를", "공부", "하", "ㅂ니다"]
→ BPE 적용: ["자연어", "처리", "를", "공부", "합니다"]
</code></pre></div></div>

<p><strong>실험 결과</strong> (Lee et al., 2020):</p>
<ul>
  <li>KorNLI, KorSTS, NSMC, PAWS-X: <strong>형태소 + BPE가 최적</strong></li>
  <li>KorQuAD (QA): BPE 단독이 최적 (정확한 span 추출에 유리)</li>
</ul>

<p>도구: Mecab-ko, KoNLPy (Okt, Komoran, Hannanum)</p>

<p>단점: 형태소 분석기에 의존. 분석기의 오류가 토큰화에 전파됨.</p>

<h3 id="32-형태소-인식-서브워드--자소-분해">3.2. 형태소 인식 서브워드 + 자소 분해</h3>

<p>형태소 유형 정보를 BPE 학습 과정에 통합하는 방식 (Jeon et al., 2023):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>한글 음절 "한" → 자소 분해 → "ㅎ", "ㅏ", "ㄴ"
</code></pre></div></div>

<ul>
  <li>어휘 크기 축소 (한글 음절 11,172개 → 자소 67개)</li>
  <li>형태소 유형(어간/어미/조사) 정보를 학습에 반영</li>
  <li>구문적 태스크(NIKL-CoLA)에서 특히 효과적</li>
</ul>

<h3 id="33-thunder-tok-규칙-기반-전처리--분기-엔트로피-2025-서울대">3.3. Thunder-Tok: 규칙 기반 전처리 + 분기 엔트로피 (2025, 서울대)</h3>

<p>가장 최근의 접근법. 핵심 아이디어:</p>

<ol>
  <li><strong>규칙 기반 전처리</strong>: 한국어 언어 구조에 맞는 분할 규칙 적용</li>
  <li><strong>시드 어휘 생성</strong>: 언어학적 단위를 닮은 토큰으로 초기 어휘 구성</li>
  <li><strong>분기 엔트로피 기반 선택</strong>: 통계적으로 의미 있는 경계를 자동 탐지</li>
</ol>

<p>결과:</p>
<ul>
  <li>BPE 대비 <strong>fertility 약 10% 감소</strong></li>
  <li>추론 속도 <strong>~10% 향상</strong> (토큰 수 감소에 비례)</li>
  <li>다운스트림 성능 저하 없음</li>
</ul>

<h3 id="34-어휘-확장-eeve-방식">3.4. 어휘 확장 (EEVE 방식)</h3>

<p>영어 중심 LLM에 한국어 어휘를 추가하는 접근 (Yoo et al., 2024):</p>

<ol>
  <li>기존 영어 토크나이저에 한국어 서브워드 추가</li>
  <li>새 토큰의 임베딩을 기존 토큰의 가중 평균으로 초기화</li>
  <li>기존 파라미터는 동결, 새 임베딩만 학습</li>
</ol>

<p>SOLAR-10.7B, Phi-2에 적용하여 한국어 처리 효율을 대폭 개선.</p>

<hr />

<h2 id="4-실무-가이드-어떤-전략을-써야-하는가">4. 실무 가이드: 어떤 전략을 써야 하는가</h2>

<h3 id="의사결정-트리">의사결정 트리</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>한국어 전용 모델을 처음부터 학습?
├── Yes → 형태소 + BPE 하이브리드 또는 Thunder-Tok
└── No
    └── 영어 중심 모델을 한국어에 적용?
        ├── 파인튜닝 가능 → EEVE 방식 어휘 확장
        └── API만 사용 → 프롬프트 최적화 (토큰 절약 기법)
</code></pre></div></div>

<h3 id="rag임베딩에서의-한국어-토큰화">RAG/임베딩에서의 한국어 토큰화</h3>

<p>한국어 RAG 시스템 구축 시:</p>
<ul>
  <li><strong>청킹(Chunking)</strong>: 형태소 분석 기반 문장 분리가 BPE 기반보다 정확</li>
  <li><strong>임베딩 모델</strong>: BGE-M3 (다국어), KoSimCSE (한국어 특화)</li>
  <li><strong>검색 품질</strong>: 형태소 분석 전처리 → BM25 검색 성능 향상</li>
</ul>

<hr />

<h2 id="5-미래-방향">5. 미래 방향</h2>

<h3 id="토크나이저-없는-모델-tokenizer-free">토크나이저 없는 모델 (Tokenizer-Free)</h3>

<p>바이트 단위로 직접 처리하는 모델(ByT5, MegaByte)이 연구되고 있다. 토크나이저의 언어 편향 문제를 근본적으로 해결할 수 있지만, 시퀀스 길이 증가로 인한 효율성 문제가 남아 있다.</p>

<h3 id="한국어-llm-생태계">한국어 LLM 생태계</h3>

<ul>
  <li><strong>HyperCLOVA X</strong> (네이버): 한국어 최적화 토크나이저 자체 개발</li>
  <li><strong>SOLAR</strong> (업스테이지): 한국어 어휘 확장 적용</li>
  <li><strong>Gemma 4</strong>: 다국어 BPE 기반이지만 한국어 토큰 효율은 여전히 과제</li>
</ul>

<hr />

<h2 id="정리">정리</h2>

<table>
  <thead>
    <tr>
      <th>접근법</th>
      <th>Fertility</th>
      <th>성능</th>
      <th>복잡도</th>
      <th>적합 상황</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>BPE (raw)</td>
      <td>높음</td>
      <td>기준</td>
      <td>낮음</td>
      <td>QA 태스크, 빠른 프로토타이핑</td>
    </tr>
    <tr>
      <td>형태소 + BPE</td>
      <td>중간</td>
      <td><strong>최고</strong></td>
      <td>중간</td>
      <td>한국어 NLU/NMT</td>
    </tr>
    <tr>
      <td>자소 분해</td>
      <td>낮음</td>
      <td>좋음</td>
      <td>중간</td>
      <td>어휘 크기 제약 환경</td>
    </tr>
    <tr>
      <td>Thunder-Tok</td>
      <td>낮음</td>
      <td>좋음</td>
      <td>높음</td>
      <td>추론 효율 최적화</td>
    </tr>
    <tr>
      <td>어휘 확장</td>
      <td>중간</td>
      <td>좋음</td>
      <td>중간</td>
      <td>영어 모델 한국어 적용</td>
    </tr>
  </tbody>
</table>

<p>한국어 토큰화의 핵심 교훈: <strong>“언어 독립적”이라는 BPE의 강점이 교착어에서는 약점이 된다.</strong> 언어학적 지식을 적절히 주입하면 효율과 성능 모두를 개선할 수 있다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/transformer/">트랜스포머 (Transformer)</a></li>
  <li><a href="/concepts/embedding/">임베딩 (Embedding)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Lee et al., “An Empirical Study of Tokenization Strategies for Various Korean NLP Tasks” (2020), <a href="https://arxiv.org/abs/2010.02534">arXiv:2010.02534</a></li>
  <li>Jeon et al., “Improving Korean NLP Tasks with Linguistically Informed Subword Tokenization” (2023), <a href="https://arxiv.org/abs/2311.03928">arXiv:2311.03928</a></li>
  <li>Cho et al., “Thunder-Tok: Minimizing Tokens per Word in Tokenizing Korean Texts” (2025), <a href="https://arxiv.org/abs/2506.15138">arXiv:2506.15138</a></li>
  <li>Yoo et al., “EEVE-Korean: Efficient and Effective Vocabulary Expansion” (2024), <a href="https://arxiv.org/abs/2402.14714">arXiv:2402.14714</a></li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="NLP" /><category term="토큰화" /><category term="BPE" /><category term="한국어" /><category term="NLP" /><category term="형태소분석" /><category term="SentencePiece" /><summary type="html"><![CDATA[BPE가 한국어에서 왜 비효율적인지, 형태소 분석 하이브리드와 자소 분해가 어떻게 이를 해결하는지, 그리고 실무에서의 최적 전략을 정리한다.]]></summary></entry><entry><title type="html">LLM-Wiki로 세컨드 브레인 구축하기: Karpathy 패턴 실전 적용기</title><link href="https://mengro1102.github.io/posts/2026/05/07/llm-wiki-second-brain/" rel="alternate" type="text/html" title="LLM-Wiki로 세컨드 브레인 구축하기: Karpathy 패턴 실전 적용기" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/llm-wiki-second-brain</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/llm-wiki-second-brain/"><![CDATA[<p>2026년 4월, Andrej Karpathy가 GitHub Gist에 올린 한 장의 문서가 개인 지식 관리(PKM) 커뮤니티를 뒤흔들었다. “나는 요즘 코드보다 개인 지식 저장소 구축에 토큰을 더 많이 쓴다”는 한 마디와 함께.</p>

<p>나는 이 가이드를 읽은 직후 Obsidian 볼트를 초기화하고, 3주간 실제로 운영해봤다. 이 글은 그 과정에서 얻은 실전 경험을 정리한 것이다.</p>

<hr />

<h2 id="1-pkm은-왜-실패하는가">1. PKM은 왜 실패하는가</h2>

<p>Evernote → Notion → Roam Research → Obsidian. 도구는 바뀌어도 결말은 같다. 3개월 안에 포기.</p>

<p>근본 원인은 단순하다:</p>

<blockquote>
  <p><strong>입력 마찰 &gt; 검색 가치 = 시스템 사망</strong></p>
</blockquote>

<p>노트를 정리하고, 태그를 달고, 링크를 연결하는 “북키핑” 비용이 나중에 검색해서 얻는 가치보다 빠르게 증가한다. 위키가 커질수록 유지보수 부담이 기하급수적으로 늘어나고, 결국 포기한다.</p>

<p>Karpathy의 통찰은 이 공식을 뒤집는 것이다: <strong>LLM이 북키핑을 담당하면 유지보수 비용이 거의 0에 수렴한다.</strong></p>

<hr />

<h2 id="2-llm-wiki-vs-rag-근본적-차이">2. LLM Wiki vs RAG: 근본적 차이</h2>

<p>대부분의 LLM 문서 활용은 RAG(Retrieval-Augmented Generation) 방식이다. NotebookLM, ChatGPT 파일 업로드 등. 매번 원문에서 정보를 재추출하며, <strong>지식의 누적이 없다.</strong></p>

<p>LLM Wiki는 다르다:</p>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>RAG</th>
      <th>LLM Wiki</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>지식 저장</td>
      <td>원문 청크</td>
      <td>구조화된 위키 페이지</td>
    </tr>
    <tr>
      <td>업데이트</td>
      <td>없음 (매번 재검색)</td>
      <td>점진적 축적</td>
    </tr>
    <tr>
      <td>교차 참조</td>
      <td>없음</td>
      <td>자동 생성·유지</td>
    </tr>
    <tr>
      <td>모순 감지</td>
      <td>불가</td>
      <td>LLM이 표시</td>
    </tr>
    <tr>
      <td>소유권</td>
      <td>플랫폼 종속</td>
      <td>로컬 마크다운 파일</td>
    </tr>
  </tbody>
</table>

<p>핵심 차이: RAG는 “검색 도구”이고, LLM Wiki는 <strong>“지식이 복리로 축적되는 시스템”</strong>이다.</p>

<hr />

<h2 id="3-아키텍처-3개-레이어">3. 아키텍처: 3개 레이어</h2>

<p>내가 구현한 구조는 Karpathy의 원본을 한국어 연구자 맥락에 맞게 변형한 것이다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>📁 01_raw/          ← 불변 원본 (LLM은 읽기만)
   ├── articles/    ← 웹 아티클 클리핑
   ├── papers/      ← 논문 PDF + 마크다운 변환
   ├── transcripts/ ← 유튜브/팟캐스트 트랜스크립트
   └── notes/       ← 수기 메모

📁 02_wiki/         ← LLM이 생성·유지하는 위키
   ├── concepts/    ← 개념 페이지 (attention, LoRA, ...)
   ├── entities/    ← 인물/조직/모델 페이지
   ├── sources/     ← 소스별 요약 페이지
   ├── syntheses/   ← 종합 분석 페이지
   ├── index.md     ← 전체 카탈로그
   └── log.md       ← 작업 이력 (append-only)

📁 03_output/       ← 위키에서 파생된 결과물
   ├── blog/        ← 블로그 포스트
   ├── portfolio/   ← 포트폴리오
   └── slides/      ← 발표자료
</code></pre></div></div>

<h3 id="핵심-원칙">핵심 원칙</h3>

<ul>
  <li><strong>01_raw는 진실의 원천(source of truth)</strong>. LLM은 절대 수정하지 않는다.</li>
  <li><strong>02_wiki는 LLM이 소유</strong>. 사용자는 읽기만, LLM이 쓰기.</li>
  <li><strong>03_output은 위키에서 파생</strong>. 블로그 포스트도 위키 기반으로 생성.</li>
</ul>

<hr />

<h2 id="4-워크플로우-ingest--query--lint--output">4. 워크플로우: Ingest → Query → Lint → Output</h2>

<h3 id="41-ingest-원본--위키">4.1. Ingest (원본 → 위키)</h3>

<p>새 소스가 <code class="language-plaintext highlighter-rouge">01_raw/</code>에 들어오면:</p>

<ol>
  <li>LLM이 원문을 읽는다</li>
  <li>사용자와 핵심 내용을 논의한다</li>
  <li><code class="language-plaintext highlighter-rouge">02_wiki/sources/</code>에 요약 페이지를 생성한다</li>
  <li>관련 <code class="language-plaintext highlighter-rouge">concepts/</code>, <code class="language-plaintext highlighter-rouge">entities/</code> 페이지를 갱신한다</li>
  <li><code class="language-plaintext highlighter-rouge">index.md</code>를 업데이트한다</li>
  <li><code class="language-plaintext highlighter-rouge">log.md</code>에 기록한다</li>
</ol>

<p>단일 소스 하나가 10~15개 위키 페이지에 영향을 줄 수 있다. 이 교차 참조 업데이트를 사람이 수동으로 하면 30분. LLM은 2분.</p>

<h3 id="42-query-질의--답변">4.2. Query (질의 → 답변)</h3>

<p><code class="language-plaintext highlighter-rouge">index.md</code>에서 관련 페이지를 탐색하고, 그래프 기반 탐색을 병행하여 종합 답변을 생성한다. 가치 있는 답변은 <code class="language-plaintext highlighter-rouge">syntheses/</code>에 저장하여 지식으로 축적.</p>

<h3 id="43-lint-건강-점검">4.3. Lint (건강 점검)</h3>

<p>주기적으로 위키 상태를 점검한다:</p>
<ul>
  <li>페이지 간 모순 확인</li>
  <li>고아 페이지(인바운드 링크 없는 페이지) 탐지</li>
  <li>누락된 개념 식별</li>
  <li>교차 참조 보완</li>
</ul>

<h3 id="44-output-위키--결과물">4.4. Output (위키 → 결과물)</h3>

<p>위키가 충분히 성숙하면 블로그 포스트, 포트폴리오, 발표자료로 변환한다. 이 글 자체가 Output 워크플로우의 산물이다.</p>

<hr />

<h2 id="5-인과-관계-표기-지식-그래프의-방향성">5. 인과 관계 표기: 지식 그래프의 방향성</h2>

<p>위키링크 <code class="language-plaintext highlighter-rouge">[[개념]]</code>은 “연결”만 표현한다. 하지만 지식 간에는 방향성 있는 인과 관계가 존재한다. 이를 위해 별도의 callout 컨벤션을 도입했다:</p>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gt">&gt; [!causal] 인과 관계</span>
<span class="gt">&gt; [[메타러닝]] →(가능하게 함)→ [[DiscoRL]]의 RL 규칙 자동 발견</span>
<span class="gt">&gt; 신뢰도: 높음 | 출처: [[discovering-sota-rl-algorithms]]</span>
</code></pre></div></div>

<p>허용 관계 유형:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">→(가능하게 함)→</code> : A가 B를 가능하게 함</li>
  <li><code class="language-plaintext highlighter-rouge">→(성능 향상)→</code> : A가 B의 성능을 향상시킴</li>
  <li><code class="language-plaintext highlighter-rouge">→(기반이 됨)→</code> : A가 B의 이론적/기술적 기반</li>
  <li><code class="language-plaintext highlighter-rouge">→(대체함)→</code> : A가 B를 대체함</li>
</ul>

<p>이 인과 관계를 파싱하면 방향 그래프가 만들어지고, 순환 참조나 모순을 자동 탐지할 수 있다.</p>

<hr />

<h2 id="6-3주-운영-후-실감한-것들">6. 3주 운영 후 실감한 것들</h2>

<h3 id="효과가-있었던-것">효과가 있었던 것</h3>

<ul>
  <li><strong>지식의 복리 효과</strong>: 소스가 20개를 넘어가면서 새 소스를 인제스트할 때 기존 페이지와의 연결이 자동으로 풍부해졌다. 양자화 페이지에 Gemma 4 적용 사례가 자연스럽게 추가되는 식.</li>
  <li><strong>검색 없는 탐색</strong>: <code class="language-plaintext highlighter-rouge">index.md</code>와 위키링크만으로 원하는 정보에 2~3홉 이내로 도달. 벡터 DB 없이도 ~100개 소스 규모에서 충분히 작동.</li>
  <li><strong>블로그 포스트 생산 속도</strong>: 위키가 충분히 채워진 주제는 포스트 초안을 30분 내에 생성 가능.</li>
</ul>

<h3 id="주의할-점">주의할 점</h3>

<ul>
  <li><strong>LLM의 환각</strong>: 위키 페이지에 원본에 없는 내용이 슬며시 들어갈 수 있다. <code class="language-plaintext highlighter-rouge">sources</code> frontmatter로 출처를 강제하고, Lint 시 검증.</li>
  <li><strong>컨텍스트 한계</strong>: 위키가 커지면 LLM이 전체를 한 번에 읽지 못한다. <code class="language-plaintext highlighter-rouge">index.md</code>를 진입점으로 삼아 필요한 페이지만 선택적으로 로드하는 전략이 필수.</li>
  <li><strong>초기 투자</strong>: 스키마 설계, 컨벤션 정립, 첫 10개 소스 인제스트까지는 수동 개입이 많다. 이후부터 자동화 효과가 체감됨.</li>
</ul>

<hr />

<h2 id="7-기술-스택">7. 기술 스택</h2>

<table>
  <thead>
    <tr>
      <th>구성 요소</th>
      <th>선택</th>
      <th>이유</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>에디터</td>
      <td>Obsidian</td>
      <td>위키링크, 그래프 뷰, 플러그인 생태계</td>
    </tr>
    <tr>
      <td>LLM 인터페이스</td>
      <td>Kiro (VS Code)</td>
      <td>파일 시스템 직접 접근, MCP 지원</td>
    </tr>
    <tr>
      <td>버전 관리</td>
      <td>Git</td>
      <td>변경 이력, 롤백, 협업</td>
    </tr>
    <tr>
      <td>그래프 시각화</td>
      <td>자체 Python 스크립트</td>
      <td>인과 관계 파싱 → graph.json → 시각화</td>
    </tr>
    <tr>
      <td>블로그</td>
      <td>Jekyll (Chirpy 테마)</td>
      <td>GitHub Pages 무료 호스팅</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="8-karpathy가-말한-4가지-장점">8. Karpathy가 말한 4가지 장점</h2>

<ol>
  <li><strong>명시성(Explicit)</strong>: AI가 무엇을 알고 모르는지 위키 페이지로 직접 확인 가능</li>
  <li><strong>데이터 소유권(Yours)</strong>: 로컬 마크다운 파일. 플랫폼 종속 없음</li>
  <li><strong>파일 우선(File over app)</strong>: 범용 포맷이라 어떤 도구든 호환</li>
  <li><strong>AI 선택 자유(BYOAI)</strong>: Claude, GPT, 로컬 모델 등 자유롭게 교체 가능</li>
</ol>

<hr />

<h2 id="9-결론-누가-유지-관리하는가">9. 결론: 누가 유지 관리하는가</h2>

<p>Vannevar Bush가 1945년 Memex를 구상했을 때 해결하지 못한 문제가 있었다: <strong>“누가 이 지식 저장소를 유지 관리하는가?”</strong></p>

<p>80년이 지나서야 답이 나왔다. LLM이 한다.</p>

<p>입력 마찰을 0에 가깝게 낮추고, 교차 참조를 자동으로 유지하며, 모순을 감지하고, 지식을 복리로 축적한다. 사용자는 소싱과 질문에만 집중하면 된다.</p>

<p>PKM의 역사는 실패의 역사였다. LLM Wiki는 그 공식을 처음으로 뒤집을 수 있는 패턴이다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/rag/">RAG (Retrieval-Augmented Generation)</a></li>
  <li><a href="/concepts/mcp/">MCP (Model Context Protocol)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Andrej Karpathy, “LLM Wiki Guide” (2026), GitHub Gist</li>
  <li>NEWIT, “카파시도 못 말한 LLM-Wiki의 진실” (2026), YouTube</li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="PKM" /><category term="LLM-Wiki" /><category term="PKM" /><category term="Obsidian" /><category term="Karpathy" /><category term="세컨드브레인" /><category term="MCP" /><summary type="html"><![CDATA[Andrej Karpathy의 LLM Wiki 패턴을 실제로 구현하고 운영한 경험을 공유한다. 3레이어 아키텍처, 워크플로우, 그리고 PKM이 실패하는 이유와 LLM이 그 공식을 뒤집는 방법까지.]]></summary></entry><entry><title type="html">LoRA 딥다이브: 저랭크 분해로 LLM을 효율적으로 파인튜닝하는 원리</title><link href="https://mengro1102.github.io/posts/2026/05/07/lora-deep-dive/" rel="alternate" type="text/html" title="LoRA 딥다이브: 저랭크 분해로 LLM을 효율적으로 파인튜닝하는 원리" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/lora-deep-dive</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/lora-deep-dive/"><![CDATA[<p>70B 모델을 파인튜닝하려면 FP16 기준 140GB 이상의 VRAM이 필요하다. gradient와 optimizer 상태까지 합치면 가중치의 2~3배. 현실적으로 대부분의 연구자에게 불가능한 수치다.</p>

<p>2021년, Microsoft Research에서 이 문제에 대한 우아한 해법을 내놓았다. <strong>LoRA(Low-Rank Adaptation)</strong>. 모델 가중치를 얼리고(freeze), 아주 작은 저랭크 행렬만 학습하여 간접적으로 가중치를 업데이트하는 기법이다.</p>

<hr />

<h2 id="1-fully-fine-tuning이-비현실적인-이유">1. Fully Fine-Tuning이 비현실적인 이유</h2>

<p>LLM의 학습 과정에서 GPU에 올라가는 것들을 정리하면:</p>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>크기 (대략)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>모델 가중치 (W)</td>
      <td>1×</td>
    </tr>
    <tr>
      <td>Gradient</td>
      <td>1×</td>
    </tr>
    <tr>
      <td>Optimizer 상태 (Adam: m, v)</td>
      <td>2×</td>
    </tr>
    <tr>
      <td><strong>합계</strong></td>
      <td><strong>~4×</strong></td>
    </tr>
  </tbody>
</table>

<p>7B 모델이 FP16으로 14GB라면, 학습 시에는 약 56GB가 필요하다. 70B면 560GB. 단일 GPU로는 불가능하고, 멀티 GPU 병렬화를 해도 비용이 막대하다.</p>

<p>핵심 질문: <strong>가중치 전체를 업데이트하지 않고도 동등한 성능을 낼 수 있을까?</strong></p>

<hr />

<h2 id="2-lora의-핵심-사상-저랭크-가설">2. LoRA의 핵심 사상: 저랭크 가설</h2>

<p>LoRA의 출발점은 하나의 가설이다:</p>

<blockquote>
  <p>Fine-Tuning 시 가중치 변화량 ΔW는 <strong>저랭크(low-rank) 구조</strong>를 가진다.</p>
</blockquote>

<p>즉, 수십억 개의 파라미터가 변하지만, 그 변화의 “본질적 차원”은 전체 파라미터 수보다 훨씬 작다. 마치 고차원 공간에서의 움직임이 실제로는 저차원 부분공간 위에서만 일어나는 것과 같다.</p>

<p>이 가설이 맞다면, ΔW를 직접 학습하는 대신 저랭크 행렬의 곱으로 근사할 수 있다.</p>

<hr />

<h2 id="3-수학적-원리">3. 수학적 원리</h2>

<h3 id="31-저랭크-분해-low-rank-decomposition">3.1. 저랭크 분해 (Low-Rank Decomposition)</h3>

<p>원본 가중치 행렬 $W \in \mathbb{R}^{d \times k}$를 freeze하고, 두 개의 작은 행렬을 도입한다:</p>

\[W' = W + \Delta W = W + B \cdot A\]

<p>여기서:</p>
<ul>
  <li>$A \in \mathbb{R}^{r \times k}$ — 다운프로젝션 (LoRA_A)</li>
  <li>$B \in \mathbb{R}^{d \times r}$ — 업프로젝션 (LoRA_B)</li>
  <li>$r \ll d$ — 랭크. 보통 4, 8, 16 정도</li>
</ul>

<h3 id="32-forward-pass-구조">3.2. Forward Pass 구조</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>입력 x → [Frozen W] → h₁
       → [LoRA_A → LoRA_B] → h₂
       → h = h₁ + h₂  (단순 덧셈)
</code></pre></div></div>

<p>학습 시에는 A와 B만 gradient가 흐른다. W는 완전히 고정.</p>

<h3 id="33-파라미터-절감-효과">3.3. 파라미터 절감 효과</h3>

<p>원본 W의 파라미터 수: $d \times k$</p>

<p>LoRA 추가 파라미터 수: $d \times r + r \times k = r(d + k)$</p>

<p>$d = k = 4096$, $r = 8$이라면:</p>
<ul>
  <li>원본: 16,777,216개</li>
  <li>LoRA: 65,536개 (원본의 <strong>0.39%</strong>)</li>
</ul>

<hr />

<h2 id="4-어디에-적용하는가-weight-type-선택">4. 어디에 적용하는가: Weight Type 선택</h2>

<p>Transformer의 Self-Attention 레이어에는 4개의 가중치 행렬이 있다:</p>

<table>
  <thead>
    <tr>
      <th>Weight Type</th>
      <th>역할</th>
      <th>차원</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$W_q$</td>
      <td>Query 투영</td>
      <td>$d \times d$</td>
    </tr>
    <tr>
      <td>$W_k$</td>
      <td>Key 투영</td>
      <td>$d \times d$</td>
    </tr>
    <tr>
      <td>$W_v$</td>
      <td>Value 투영</td>
      <td>$d \times d$</td>
    </tr>
    <tr>
      <td>$W_o$</td>
      <td>Output 투영</td>
      <td>$d \times d$</td>
    </tr>
  </tbody>
</table>

<p>논문의 실험 결과, <strong>Query + Key에 적용했을 때 최고 성능</strong>을 보였다. 이는 어텐션 패턴(어떤 토큰이 어떤 토큰을 바라보는지)을 조정하는 것이 Fine-Tuning의 핵심임을 시사한다.</p>

<hr />

<h2 id="5-lora의-4가지-장점">5. LoRA의 4가지 장점</h2>

<h3 id="51-성능-fully-fine-tuning과-동등하거나-우수">5.1. 성능: Fully Fine-Tuning과 동등하거나 우수</h3>

<p>18M 파라미터만으로 다양한 Downstream task에서 Full Fine-Tuning 수준의 성능을 달성.</p>

<h3 id="52-vram-절감">5.2. VRAM 절감</h3>

<p>W를 freeze하면 gradient와 optimizer 텐서가 GPU에 로드되지 않는다. 학습 대상은 오직 A와 B뿐.</p>

<h3 id="53-추론-속도-동일">5.3. 추론 속도 동일</h3>

<p>학습 완료 후 $W’ = W + B \cdot A$로 합산하면, 추론 시에는 단일 행렬 연산. 추가 연산량 제로.</p>

<h3 id="54-원복-용이">5.4. 원복 용이</h3>

<p>더한 만큼 빼면 원본 모델로 즉시 복원. 여러 태스크용 LoRA 어댑터를 스왑하며 사용 가능.</p>

<hr />

<h2 id="6-실무-적용-시나리오">6. 실무 적용 시나리오</h2>

<h3 id="로컬-gpu에서의-도메인-특화-llm">로컬 GPU에서의 도메인 특화 LLM</h3>

<p><a href="/concepts/quantization/">양자화(Quantization)</a>와 LoRA를 결합하면:</p>

<ol>
  <li>4비트 양자화로 모델을 24GB GPU에 로드</li>
  <li>LoRA로 도메인 데이터에 파인튜닝</li>
  <li>추론 시 합산하여 단일 모델로 서빙</li>
</ol>

<p>이것이 <strong>QLoRA</strong> 패턴이며, Gemma 4 같은 오픈소스 모델에 Hugging Face TRL, Unsloth 등으로 바로 적용 가능하다.</p>

<h3 id="멀티-태스크-어댑터">멀티 태스크 어댑터</h3>

<p>하나의 베이스 모델에 여러 LoRA 어댑터를 학습해두고, 요청에 따라 동적으로 로드:</p>
<ul>
  <li>코드 생성용 LoRA</li>
  <li>한국어 대화용 LoRA</li>
  <li>의료 도메인용 LoRA</li>
</ul>

<hr />

<h2 id="7-한계와-후속-연구">7. 한계와 후속 연구</h2>

<p>LoRA가 만능은 아니다:</p>

<ul>
  <li><strong>랭크 r 선택</strong>: 너무 작으면 표현력 부족, 너무 크면 효율성 감소. 태스크별 최적값이 다름.</li>
  <li><strong>적용 레이어 선택</strong>: Q+K가 최적이라는 결과는 특정 실험 조건에서의 결론. 모델/태스크에 따라 다를 수 있음.</li>
  <li><strong>복잡한 태스크</strong>: 대규모 도메인 전환(예: 영어→한국어)에서는 Full Fine-Tuning 대비 성능 갭이 존재할 수 있음.</li>
</ul>

<p>후속 연구로 QLoRA, DoRA, LoRA+, AdaLoRA 등이 이 한계들을 개선하고 있다.</p>

<hr />

<h2 id="정리">정리</h2>

<table>
  <thead>
    <tr>
      <th>항목</th>
      <th>Fully Fine-Tuning</th>
      <th>LoRA</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>학습 파라미터</td>
      <td>전체 W</td>
      <td>A, B만 (0.1~1%)</td>
    </tr>
    <tr>
      <td>VRAM</td>
      <td>W × 4</td>
      <td>W × 1 + α</td>
    </tr>
    <tr>
      <td>추론 속도</td>
      <td>기준</td>
      <td>동일</td>
    </tr>
    <tr>
      <td>원복</td>
      <td>불가</td>
      <td>즉시 가능</td>
    </tr>
    <tr>
      <td>성능</td>
      <td>기준</td>
      <td>동등~우수</td>
    </tr>
  </tbody>
</table>

<p>LoRA의 핵심 통찰은 단순하다: <strong>거대한 모델의 변화는 생각보다 저차원적이다.</strong> 이 가설 하나가 LLM 파인튜닝의 민주화를 이끌었다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/quantization/">양자화 (Quantization)</a></li>
  <li><a href="/concepts/transformer/">트랜스포머 (Transformer)</a></li>
  <li><a href="/concepts/attention/">어텐션 (Attention)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Hu et al., “LoRA: Low-Rank Adaptation of Large Language Models” (2021), arXiv:2106.09685</li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="LLM" /><category term="LoRA" /><category term="Fine-Tuning" /><category term="PEFT" /><category term="LLM" /><category term="Transformer" /><summary type="html"><![CDATA[LoRA(Low-Rank Adaptation)의 핵심 원리를 수식과 직관으로 풀어본다. 왜 모델 가중치를 직접 건드리지 않고도 성능을 끌어올릴 수 있는지, 그 수학적 근거와 실무 적용까지.]]></summary></entry><entry><title type="html">양자화 3대 기법 비교: GPTQ vs AWQ vs GGUF — 로컬 AI 시대의 열쇠</title><link href="https://mengro1102.github.io/posts/2026/05/07/quantization-gptq-awq-gguf/" rel="alternate" type="text/html" title="양자화 3대 기법 비교: GPTQ vs AWQ vs GGUF — 로컬 AI 시대의 열쇠" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/quantization-gptq-awq-gguf</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/quantization-gptq-awq-gguf/"><![CDATA[<p>70B 모델은 FP16 기준 140GB VRAM이 필요하다. RTX 4090(24GB)으로는 로드조차 불가능하다.</p>

<p>하지만 4비트 양자화를 적용하면 ~35GB로 축소된다. 놀랍게도 원본 성능의 95% 이상을 유지하면서. 이것이 로컬 AI 시대를 가능하게 만든 핵심 기술이다.</p>

<hr />

<h2 id="1-양자화란-무엇인가">1. 양자화란 무엇인가</h2>

<p>모델 가중치의 숫자 정밀도를 낮추는 기술이다. FP16(16비트 부동소수점)을 INT4(4비트 정수)로 변환하면 메모리 사용량이 1/4로 줄어든다.</p>

<h3 id="기본-수식">기본 수식</h3>

\[W_q = \text{round}\left(\frac{W}{S}\right) + Z\]

<ul>
  <li><strong>W</strong>: 원본 가중치 (FP16 실수값)</li>
  <li><strong>S (Scale Factor)</strong>: 데이터 범위를 압축하는 스케일링 팩터</li>
  <li><strong>Z (Zero-point)</strong>: 비대칭 분포 보정을 위한 영점</li>
  <li><strong>round()</strong>: 반올림. 실수를 정수 버킷에 매핑</li>
</ul>

<h3 id="왜-95-성능이-유지되는가">왜 95% 성능이 유지되는가?</h3>

<p>뉴런 간 연결 강도(가중치)의 미세한 소수점 값이 무뎌져도, 거대한 네트워크가 만들어내는 전체적인 문맥 파악의 논리 구조는 쉽게 붕괴되지 않기 때문이다. 수십억 개의 파라미터가 만드는 “집단적 패턴”은 개별 값의 정밀도보다 훨씬 견고하다.</p>

<hr />

<h2 id="2-gptq-열-단위-순차-보상-gpu-전용">2. GPTQ: 열 단위 순차 보상 (GPU 전용)</h2>

<h3 id="원리">원리</h3>

<p>가중치 행렬을 <strong>열(column) 단위</strong>로 순차 양자화한다. 핵심 아이디어: 앞선 열을 양자화할 때 발생한 오차를 뒤 열의 가중치를 조정하여 보상한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>열 1 양자화 → 오차 발생
  ↓ 오차를 열 2~N에 분배
열 2 양자화 → 오차 발생
  ↓ 오차를 열 3~N에 분배
...
</code></pre></div></div>

<p>이 방식은 Optimal Brain Surgeon(OBS) 프레임워크에서 유래했다. 각 열의 양자화가 전체 출력에 미치는 영향을 Hessian 행렬로 추정하고, 후속 열에서 보상한다.</p>

<h3 id="보정-데이터">보정 데이터</h3>

<p>~128개 텍스트 샘플로 활성화 값을 수집한다. 이 데이터가 “어떤 가중치가 출력에 얼마나 영향을 주는지”를 추정하는 데 사용된다.</p>

<h3 id="특징">특징</h3>

<ul>
  <li>4비트에서도 원본과 유사한 품질</li>
  <li>7B 모델 수 분 내 양자화 완료</li>
  <li>GPU 전용 (CUDA 커널 필요)</li>
  <li>추론 시 역양자화(dequantization) 필요</li>
  <li>vLLM, TGI와 호환</li>
</ul>

<hr />

<h2 id="3-awq-활성화-기반-채널-보존-gpu-전용">3. AWQ: 활성화 기반 채널 보존 (GPU 전용)</h2>

<h3 id="원리-1">원리</h3>

<p>AWQ(Activation-aware Weight Quantization)의 핵심 통찰:</p>

<blockquote>
  <p><strong>모든 가중치가 동등하지 않다.</strong> 활성화(Activation) 크기가 큰 채널이 출력에 더 큰 영향을 준다.</p>
</blockquote>

<p>보정 데이터를 통해 각 가중치 채널의 활성화 크기를 측정하고, 중요 채널은 높은 정밀도를 유지한다. 덜 중요한 채널은 공격적으로 양자화해도 전체 성능에 미치는 영향이 적다.</p>

<h3 id="gptq와의-차이">GPTQ와의 차이</h3>

<ul>
  <li>GPTQ: 오차를 <strong>후속 열에 분배</strong>하여 보상</li>
  <li>AWQ: 중요 채널을 <strong>사전에 식별</strong>하여 보호</li>
</ul>

<h3 id="특징-1">특징</h3>

<ul>
  <li>GPTQ보다 빠른 양자화 속도</li>
  <li>동등한 품질</li>
  <li>GPU 전용</li>
  <li>vLLM, TGI와 호환</li>
</ul>

<hr />

<h2 id="4-gguf-크로스플랫폼-호환-cpugpu">4. GGUF: 크로스플랫폼 호환 (CPU+GPU)</h2>

<h3 id="원리-2">원리</h3>

<p>GGUF(GPT-Generated Unified Format)는 llama.cpp 생태계의 표준 포맷이다. 특정 양자화 알고리즘이라기보다는 <strong>다양한 양자화 방식을 담을 수 있는 컨테이너 포맷</strong>에 가깝다.</p>

<p>핵심 강점은 <strong>CPU+GPU 혼합 추론</strong>:</p>
<ul>
  <li>GPU VRAM이 부족하면 일부 레이어를 CPU RAM에 오프로드</li>
  <li>Mac, Windows, Linux 어디서든 구동</li>
  <li>Ollama, LM Studio 등 로컬 런타임과 즉시 호환</li>
</ul>

<h3 id="양자화-레벨">양자화 레벨</h3>

<table>
  <thead>
    <tr>
      <th>레벨</th>
      <th>비트</th>
      <th>품질</th>
      <th>용도</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Q2_K</td>
      <td>~2.5bit</td>
      <td>낮음</td>
      <td>극한 메모리 제약</td>
    </tr>
    <tr>
      <td>Q4_K_M</td>
      <td>~4.5bit</td>
      <td>좋음</td>
      <td>일반 사용 권장</td>
    </tr>
    <tr>
      <td>Q5_K_M</td>
      <td>~5.5bit</td>
      <td>매우 좋음</td>
      <td>품질 우선</td>
    </tr>
    <tr>
      <td>Q8_0</td>
      <td>8bit</td>
      <td>거의 원본</td>
      <td>VRAM 여유 시</td>
    </tr>
  </tbody>
</table>

<h3 id="특징-2">특징</h3>

<ul>
  <li>크로스플랫폼 (CPU/GPU/Metal)</li>
  <li>Ollama 한 줄 설치로 즉시 사용</li>
  <li>GPU 전용 기법 대비 추론 속도 다소 느림</li>
  <li>커뮤니티 생태계가 가장 활발</li>
</ul>

<hr />

<h2 id="5-비교-테이블">5. 비교 테이블</h2>

<table>
  <thead>
    <tr>
      <th>기법</th>
      <th>타겟</th>
      <th>보상 전략</th>
      <th>양자화 속도</th>
      <th>추론 속도</th>
      <th>호환성</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GPTQ</td>
      <td>GPU</td>
      <td>열 단위 순차 보상</td>
      <td>빠름</td>
      <td>빠름</td>
      <td>vLLM, TGI</td>
    </tr>
    <tr>
      <td>AWQ</td>
      <td>GPU</td>
      <td>활성화 기반 채널 보존</td>
      <td>매우 빠름</td>
      <td>빠름</td>
      <td>vLLM, TGI</td>
    </tr>
    <tr>
      <td>GGUF</td>
      <td>CPU+GPU</td>
      <td>혼합 정밀도</td>
      <td>보통</td>
      <td>보통</td>
      <td>llama.cpp, Ollama</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="6-어떤-걸-써야-하는가-의사결정-트리">6. 어떤 걸 써야 하는가: 의사결정 트리</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>GPU 서버에서 서빙? (vLLM/TGI)
├── Yes → AWQ (속도 우선) 또는 GPTQ (품질 우선)
└── No
    └── 로컬 PC에서 개인 사용?
        ├── NVIDIA GPU 있음 → GGUF (Q4_K_M) + GPU 오프로드
        └── CPU만 또는 Mac → GGUF (Q4_K_M)
</code></pre></div></div>

<p>실무에서의 경험칙:</p>
<ul>
  <li><strong>프로덕션 서빙</strong>: AWQ + vLLM. 양자화 속도와 추론 성능 모두 우수.</li>
  <li><strong>로컬 실험/개인 사용</strong>: GGUF + Ollama. 설치 1분, 즉시 사용.</li>
  <li><strong>품질 최우선</strong>: GPTQ. 보정 데이터를 도메인에 맞게 준비하면 품질 극대화.</li>
</ul>

<hr />

<h2 id="7-gemma-4에서의-양자화">7. Gemma 4에서의 양자화</h2>

<p>Gemma 4는 양자화에 최적화된 설계를 갖추고 있다:</p>

<ul>
  <li><strong>MoE (26B/4B active)</strong>: 활성 파라미터가 4B뿐이므로 양자화 시 메모리 효율 극대화</li>
  <li><strong>Shared KV Cache</strong>: KV 캐시 공유로 양자화 후에도 추론 메모리 절감</li>
  <li><strong>Apache 2 라이선스</strong>: 자유롭게 양자화·배포 가능</li>
</ul>

<p>Hugging Face에서 GPTQ, AWQ, GGUF 버전 모두 커뮤니티가 제공하고 있어, 용도에 맞게 선택하면 된다.</p>

<hr />

<h2 id="8-양자화--lora--로컬-ai의-완성">8. 양자화 + LoRA = 로컬 AI의 완성</h2>

<p><a href="/posts/quantization-gptq-awq-gguf/">양자화</a>와 <a href="/posts/lora-deep-dive/">LoRA</a>를 결합하면:</p>

<ol>
  <li>4비트 양자화로 모델을 24GB GPU에 로드</li>
  <li>LoRA로 도메인 데이터에 파인튜닝 (QLoRA)</li>
  <li>추론 시 합산하여 단일 모델로 서빙</li>
</ol>

<p>이것이 “개인 GPU에서 도메인 특화 LLM을 구축하는” 현실적 경로다.</p>

<hr />

<h2 id="정리">정리</h2>

<p>양자화는 단순한 압축 기술이 아니다. <strong>로컬 AI 시대의 민주화 도구</strong>다.</p>

<ul>
  <li>70B 모델을 소비자 GPU에서 구동 가능하게 만들고</li>
  <li>95% 이상의 성능을 유지하며</li>
  <li>오픈소스 생태계와 결합하여 누구나 접근 가능한 AI를 실현한다</li>
</ul>

<p>GPTQ, AWQ, GGUF는 각각의 트레이드오프가 있지만, 공통된 메시지는 하나다: <strong>거대한 모델의 지능은 소수점 아래 자릿수에 있지 않다.</strong></p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/posts/lora-deep-dive/">LoRA (Low-Rank Adaptation)</a></li>
  <li><a href="/concepts/transformer/">트랜스포머 (Transformer)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers” (2022)</li>
  <li>Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration” (2023)</li>
  <li>llama.cpp GGUF 포맷 명세, GitHub</li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="LLM" /><category term="양자화" /><category term="Quantization" /><category term="GPTQ" /><category term="AWQ" /><category term="GGUF" /><category term="LLM" /><category term="최적화" /><summary type="html"><![CDATA[70B 모델을 24GB GPU에서 돌리는 마법. 양자화의 원리부터 GPTQ, AWQ, GGUF 3대 기법의 동작 방식과 트레이드오프를 비교한다.]]></summary></entry><entry><title type="html">Sliding Window Attention의 한계와 RAttention: 윈도우 512로 Full Attention을 매칭하다</title><link href="https://mengro1102.github.io/posts/2026/05/07/sliding-window-attention-rattention/" rel="alternate" type="text/html" title="Sliding Window Attention의 한계와 RAttention: 윈도우 512로 Full Attention을 매칭하다" /><published>2026-05-07T00:00:00+09:00</published><updated>2026-05-07T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/05/07/sliding-window-attention-rattention</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/05/07/sliding-window-attention-rattention/"><![CDATA[<p><a href="/concepts/transformer/">트랜스포머</a>의 어텐션은 O(N²)이다. 토큰이 2배 길어지면 연산량은 4배. 이것이 긴 문맥에서 OOM이 발생하는 근본 원인이다.</p>

<p>Sliding Window Attention(SWA)은 이 문제를 O(N×W)로 줄인다. 하지만 대가가 있다: <strong>윈도우 밖 토큰을 완전히 무시한다.</strong> Apple의 RAttention 논문은 이 근본 한계를 해결하여, 윈도우 512만으로 Full Attention 성능을 매칭했다.</p>

<hr />

<h2 id="1-full-attention의-비용">1. Full Attention의 비용</h2>

<p>표준 어텐션의 수식:</p>

\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V\]

<p>시퀀스 길이 N에 대해:</p>
<ul>
  <li>연산량: O(N² × d)</li>
  <li>KV Cache (추론 시): O(N × d) — 시퀀스가 길어질수록 선형 증가</li>
</ul>

<p>128K 토큰 문맥에서 KV Cache만 수십 GB를 차지할 수 있다.</p>

<hr />

<h2 id="2-sliding-window-attention-onw로의-축소">2. Sliding Window Attention: O(N×W)로의 축소</h2>

<h3 id="원리">원리</h3>

<p>최근 W개 토큰에 대해서만 어텐션을 수행한다:</p>

\[o_t^{\text{swa}} = \frac{\sum_{i=\max(1,t-w)}^{t} \exp(q_t k_i^T) v_i}{\sum_{i=\max(1,t-w)}^{t} \exp(q_t k_i^T)}\]

<ul>
  <li>연산량: O(N × W × d) — W가 고정이면 N에 선형</li>
  <li>KV Cache: O(W × d) — <strong>상수</strong>. 시퀀스 길이와 무관</li>
</ul>

<h3 id="local-global-hybrid-gemma-4-mistral">Local-Global Hybrid (Gemma 4, Mistral)</h3>

<p>현대 모델은 SWA만 쓰지 않는다. SWA 레이어와 Full Attention 레이어를 교대 배치한다:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Layer 1: SWA (윈도우 512)    ← 로컬 문맥, 상수 메모리
Layer 2: Full Attention       ← 글로벌 문맥, O(N) 메모리
Layer 3: SWA (윈도우 512)    ← 로컬 문맥
Layer 4: Full Attention       ← 글로벌 문맥
...
</code></pre></div></div>

<p>Gemma 4는 소형 모델에서 윈도우 512, 대형 모델에서 1024를 사용한다.</p>

<h3 id="pareto-트레이드오프">Pareto 트레이드오프</h3>

<table>
  <thead>
    <tr>
      <th>윈도우 크기</th>
      <th>성능</th>
      <th>효율</th>
      <th>문제</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>4096 (Gemma 2, Mistral)</td>
      <td>Full Attention에 근접</td>
      <td>짧은 문맥에서 이점 없음</td>
      <td>보수적</td>
    </tr>
    <tr>
      <td>1024</td>
      <td>약간 저하</td>
      <td>중간</td>
      <td>—</td>
    </tr>
    <tr>
      <td>512</td>
      <td>저하</td>
      <td>높음</td>
      <td>정보 손실</td>
    </tr>
    <tr>
      <td>128</td>
      <td>심각한 저하</td>
      <td>매우 높음</td>
      <td>사용 불가</td>
    </tr>
  </tbody>
</table>

<p>핵심 딜레마: 윈도우를 줄이면 효율은 좋아지지만 성능이 떨어진다. 이 Pareto 경계를 이동시킬 수 있을까?</p>

<hr />

<h2 id="3-swa의-근본-한계">3. SWA의 근본 한계</h2>

<p>흔히 알려진 경험적 규칙:</p>

<blockquote>
  <p>layers × window_size ≥ context_length</p>
</blockquote>

<p>이 규칙은 “정보가 레이어를 거치며 전파되므로, 충분한 레이어가 있으면 먼 토큰의 정보도 도달한다”는 가정에 기반한다.</p>

<p><strong>RAttention 논문은 이것이 불충분함을 증명했다.</strong> SWA의 진짜 문제는:</p>

<ul>
  <li>윈도우 밖 토큰을 <strong>완전히 무시</strong>한다 (0% 참조)</li>
  <li>레이어 간 전파는 간접적이고 손실이 크다</li>
  <li>특히 recall-intensive 태스크(특정 정보를 정확히 기억해야 하는 경우)에서 치명적</li>
</ul>

<hr />

<h2 id="4-rattention-residual-linear-attention으로-보완">4. RAttention: Residual Linear Attention으로 보완</h2>

<h3 id="핵심-아이디어">핵심 아이디어</h3>

<p>SWA가 놓치는 “윈도우 밖 토큰”의 정보를 Linear Attention의 recurrent 상태로 캡처한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>RAttention = SWA (윈도우 내) + RLA (윈도우 밖)
</code></pre></div></div>

<h3 id="residual-linear-attention-rla-수식">Residual Linear Attention (RLA) 수식</h3>

<p>\(S_t = S_{t-1} + \phi(k_t)^T v_t\)
\(o_t^{\text{rla}} = \phi(q_t) \cdot S_{t-w-1}\)</p>

<ul>
  <li>$S_t$: 선형 어텐션의 recurrent 상태 (행렬값 hidden state)</li>
  <li>$\phi$: 특성 맵 (softmax 기반이 최적)</li>
  <li>핵심: $S_{t-w-1}$에서 읽어옴 — 윈도우 밖 토큰의 정보만 캡처</li>
</ul>

<h3 id="최종-출력">최종 출력</h3>

\[o_t = \text{RMS}(o_t^{\text{swa}}) + \text{RMS}(o_t^{\text{rla}})\]

<p>SWA의 로컬 정보와 RLA의 글로벌 정보를 합산.</p>

<h3 id="설계-특징">설계 특징</h3>

<ul>
  <li><strong>추가 파라미터 없음</strong>: SWA의 Q/K/V 투영을 그대로 재사용</li>
  <li><strong>상수 메모리 유지</strong>: RLA의 상태 $S$는 고정 크기 (d’ × d)</li>
  <li><strong>GQA 호환</strong>: Group-Query Attention과 자연스럽게 결합</li>
  <li><strong>전용 커널</strong>: chunkwise parallel 구현으로 학습 효율 유지</li>
</ul>

<hr />

<h2 id="5-실험-결과">5. 실험 결과</h2>

<h3 id="3b-12b-스케일-사전학습">3B, 12B 스케일 사전학습</h3>

<table>
  <thead>
    <tr>
      <th>설정</th>
      <th>윈도우</th>
      <th>성능 (vs Full Attention)</th>
      <th>KV Cache 절감</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SWA only</td>
      <td>4096</td>
      <td>동등</td>
      <td>짧은 문맥에서 미미</td>
    </tr>
    <tr>
      <td>SWA only</td>
      <td>512</td>
      <td><strong>저하</strong></td>
      <td>큼</td>
    </tr>
    <tr>
      <td><strong>RAttention</strong></td>
      <td><strong>512</strong></td>
      <td><strong>Full Attention 매칭</strong></td>
      <td><strong>~87% (4K 문맥)</strong></td>
    </tr>
  </tbody>
</table>

<ul>
  <li>3B와 12B 모두에서 일관된 결과</li>
  <li>윈도우 512의 RAttention이 윈도우 4096의 SWA와 동등하거나 우수</li>
</ul>

<h3 id="장문맥-성능-ruler-벤치마크">장문맥 성능 (RULER 벤치마크)</h3>

<p>RLA의 recurrent 특성이 장문맥 일반화에 기여:</p>
<ul>
  <li>SWA 대비 현저히 우수한 zero-shot 길이 일반화</li>
  <li>위치 임베딩에 대한 과도한 의존도 감소</li>
</ul>

<h3 id="학습-효율">학습 효율</h3>

<p>전용 커널 구현 + 축소된 윈도우 크기 덕분에:</p>
<ul>
  <li>Full Attention 모델과 동등한 학습 속도</li>
  <li>더 큰 윈도우의 SWA 모델과도 동등</li>
</ul>

<hr />

<h2 id="6-왜-linear-attention-단독으로는-안-되는가">6. 왜 Linear Attention 단독으로는 안 되는가</h2>

<p>순수 Linear Attention 모델은 Transformer에 미치지 못한다. 특히 recall-intensive 태스크에서. 이유:</p>

<ul>
  <li>고정 크기 상태 $S$에 모든 과거 정보를 압축해야 함</li>
  <li>정보 병목(information bottleneck)이 발생</li>
  <li>softmax 어텐션의 “선택적 집중” 능력이 없음</li>
</ul>

<p>RAttention의 해법: <strong>SWA가 로컬의 정밀한 recall을 담당하고, RLA는 글로벌의 대략적 문맥만 보완한다.</strong> 역할 분담이 핵심.</p>

<hr />

<h2 id="7-gemma-4에서의-적용">7. Gemma 4에서의 적용</h2>

<p>Gemma 4의 어텐션 설계는 RAttention 논문의 맥락에서 이해할 수 있다:</p>

<ul>
  <li><strong>소형 dense 모델</strong>: 윈도우 512 + Full Attention 교대</li>
  <li><strong>대형 모델</strong>: 윈도우 1024 + Full Attention 교대</li>
  <li><strong>Dual RoPE</strong>: sliding 레이어는 표준 RoPE, global 레이어는 proportional RoPE</li>
  <li><strong>Shared KV Cache</strong>: 마지막 N개 레이어가 이전 레이어의 KV 재사용</li>
</ul>

<p>RAttention은 이 아키텍처의 “Full Attention 레이어”를 줄이거나 제거할 수 있는 가능성을 제시한다.</p>

<hr />

<h2 id="8-시사점">8. 시사점</h2>

<h3 id="실무적-의미">실무적 의미</h3>

<ul>
  <li>윈도우 512로도 충분하다면, 추론 시 KV Cache가 극적으로 줄어듦</li>
  <li>4K 문맥에서 ~87% KV Cache 절감 → 더 긴 문맥을 같은 메모리로 처리 가능</li>
  <li>온디바이스 모델에서 특히 중요 (메모리 제약이 심한 환경)</li>
</ul>

<h3 id="연구적-의미">연구적 의미</h3>

<ul>
  <li>“layers × window ≥ context” 규칙의 불충분함을 실증</li>
  <li>SWA + Linear Attention 하이브리드가 Full Attention의 실질적 대안</li>
  <li>Recurrent 특성이 장문맥 일반화에 기여 → RNN의 부활?</li>
</ul>

<hr />

<h2 id="정리">정리</h2>

<table>
  <thead>
    <tr>
      <th>방식</th>
      <th>연산량</th>
      <th>KV Cache</th>
      <th>성능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Full Attention</td>
      <td>O(N²)</td>
      <td>O(N)</td>
      <td>기준</td>
    </tr>
    <tr>
      <td>SWA (w=4096)</td>
      <td>O(N×W)</td>
      <td>O(W)</td>
      <td>동등</td>
    </tr>
    <tr>
      <td>SWA (w=512)</td>
      <td>O(N×W)</td>
      <td>O(W)</td>
      <td>저하</td>
    </tr>
    <tr>
      <td><strong>RAttention (w=512)</strong></td>
      <td>O(N×W) + α</td>
      <td>O(W) + O(d²)</td>
      <td><strong>동등</strong></td>
    </tr>
  </tbody>
</table>

<p>RAttention의 메시지: <strong>윈도우 밖 정보를 완전히 버리지 말고, 저비용으로 요약하여 보존하라.</strong> 이 단순한 아이디어가 Pareto 경계를 이동시켰다.</p>

<hr />

<p><strong>관련 개념:</strong></p>
<ul>
  <li><a href="/concepts/attention/">어텐션 (Attention)</a></li>
  <li><a href="/concepts/transformer/">트랜스포머 (Transformer)</a></li>
</ul>

<p><strong>참고 자료:</strong></p>
<ul>
  <li>Wang et al., “RAttention: Towards the Minimal Sliding Window Size in Local-Global Attention Models” (2025), <a href="https://arxiv.org/abs/2506.15545">arXiv:2506.15545</a></li>
  <li><a href="https://machinelearning.apple.com/research/rattention">Apple Machine Learning Research</a></li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="LLM" /><category term="Attention" /><category term="SWA" /><category term="RAttention" /><category term="Transformer" /><category term="효율성" /><category term="Apple" /><summary type="html"><![CDATA[Sliding Window Attention의 O(N²) → O(N×W) 절감 원리와 근본 한계, 그리고 Apple의 RAttention이 윈도우 512만으로 Full Attention 성능을 매칭하는 방법을 분석한다.]]></summary></entry><entry><title type="html">Gemma 4를 이해하는 과정: SLM/LLM의 시작점부터 최신 멀티모달 아키텍처까지</title><link href="https://mengro1102.github.io/posts/2026/04/15/gemma4-understanding/" rel="alternate" type="text/html" title="Gemma 4를 이해하는 과정: SLM/LLM의 시작점부터 최신 멀티모달 아키텍처까지" /><published>2026-04-15T00:00:00+09:00</published><updated>2026-04-15T00:00:00+09:00</updated><id>https://mengro1102.github.io/posts/2026/04/15/gemma4-understanding</id><content type="html" xml:base="https://mengro1102.github.io/posts/2026/04/15/gemma4-understanding/"><![CDATA[<p>2026년 4월, Gemma 4가 Hugging Face에 등장했다. Google DeepMind가 개발한 오픈소스 멀티모달 SLM으로, Gemini의 소형화라고 보면 된다. 이미지, 오디오, 비디오를 입력받아 텍스트를 산출하는 Vision-Text-to-Text 모델이다.</p>

<p>본 글은 Gemma 4에 대한 이해를 위해 SLM/LLM의 시작점부터 살펴보며 해석을 수행한다.</p>

<hr />

<h2 id="1-언어-모델의-기원과-본질-단어는-어떻게-숫자가-되는가">1. 언어 모델의 기원과 본질: 단어는 어떻게 숫자가 되는가?</h2>

<p>우리는 Gemma 4와 같은 최신 AI와 대화를 나눌 때, 마치 상대방이 내 말을 ‘이해’하고 ‘생각’해서 대답하는 것처럼 느껴진다. 하지만 모델의 내부를 살펴보면, 그곳에는 오직 ‘수학’과 ‘통계’만이 존재한다.</p>

<h3 id="11-next-token-prediction의-마법">1.1. Next Token Prediction의 마법</h3>

<p>언어 모델의 본질은 주어진 문맥 뒤에 올 가장 확률이 높은 단어를 통계적으로 찍어내는 것이다.</p>

<p>“오늘 날씨가 참 [ ]” → 모델은 ‘좋다’(0.7) 또는 ‘나쁘다’(0.2)를 확률적으로 선택한다.</p>

<p>이 단순한 확률 게임을 수조 개의 토큰과 수백억 개의 파라미터 규모로 스케일업했을 때, 모델은 문장의 구조, 논리적 흐름, 세상의 보편적 지식까지 확률 분포 안에 압축하여 ‘내면화’하게 된다.</p>

<h3 id="12-토큰화-tokenization-텍스트를-조각내다">1.2. <a href="/concepts/tokenization/">토큰화 (Tokenization)</a>: 텍스트를 조각내다</h3>

<p>컴퓨터는 0과 1만 이해한다. 텍스트를 숫자로 변환하는 전처리가 필수적이다.</p>

<p>현대 LLM들은 주로 <strong><a href="/concepts/tokenization/">BPE(Byte Pair Encoding)</a></strong> 알고리즘을 사용한다. 자주 등장하는 글자 조합을 하나의 토큰으로 묶는 방식이다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"hugs" → BPE 학습 후 → ["hug", "s"]
</code></pre></div></div>

<p>BPE의 핵심 장점은 <strong>OOV(Out-of-Vocabulary) 문제 해결</strong> — 어떤 단어든 서브워드 조합으로 표현 가능하다는 것이다.</p>

<h3 id="13-임베딩-embedding-단어에-좌표를-부여하다">1.3. <a href="/concepts/embedding/">임베딩 (Embedding)</a>: 단어에 좌표를 부여하다</h3>

<p>토큰에 부여된 ID를 수천 차원의 벡터 공간 상의 좌표로 변환하는 기술이다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[King] - [Man] + [Woman] ≈ [Queen]
</code></pre></div></div>

<p><strong>Gemma 4의 혁신 — PLE (Per-Layer Embeddings):</strong> 레이어별로 토큰 특화 잔차 신호를 주입하여, 단일 임베딩에 모든 정보를 압축하는 한계를 극복.</p>

<hr />

<h2 id="2-llm의-심장-트랜스포머와-어텐션-메커니즘">2. LLM의 심장: <a href="/concepts/transformer/">트랜스포머</a>와 <a href="/concepts/attention/">어텐션 메커니즘</a></h2>

<p>“배가 부르다”와 “배를 타다”에서 ‘배’는 주변 단어에 의해 의미가 완전히 달라진다. 2017년 구글이 발표한 <strong>트랜스포머</strong>가 이 문맥 파악 문제를 해결했다.</p>

<h3 id="21-어텐션-메커니즘의-수학적-원리">2.1. <a href="/concepts/attention/">어텐션</a> 메커니즘의 수학적 원리</h3>

\[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V\]

<ul>
  <li><strong>Query (Q)</strong>: 기준 단어 — “검색어”</li>
  <li><strong>Key (K)</strong>: 다른 단어들의 특징 — “문서 키워드”</li>
  <li><strong>Value (V)</strong>: 다른 단어들의 실제 의미 — “문서 내용”</li>
</ul>

<p>이 행렬 곱셈 연산은 GPU의 CUDA 코어에서 대규모 병렬 처리에 극도로 최적화되어 있다.</p>

<h3 id="22-context-window의-구조적-한계">2.2. Context Window의 구조적 한계</h3>

<p>어텐션의 연산량은 <strong>O(N²)</strong>. 토큰이 2배 길어지면 연산량은 4배. 이것이 OOM의 근본 원인이다.</p>

<h3 id="23-sliding-window-attention과-rattention">2.3. <a href="/concepts/sliding-window-attention/">Sliding Window Attention</a>과 RAttention</h3>

<p>Gemma 4는 <strong>Local-Global Hybrid Attention</strong>을 사용한다:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Layer 1: SWA (윈도우 512)    ← 로컬 문맥
Layer 2: Full Attention       ← 글로벌 문맥
Layer 3: SWA (윈도우 512)    ← 로컬 문맥
...
</code></pre></div></div>

<p>Apple의 RAttention 논문은 SWA의 한계를 Residual Linear Attention으로 보완하여, 윈도우 512로도 Full Attention 성능을 매칭했다.</p>

<hr />

<h2 id="3-원석을-에이전트로-제련하다-모델-학습의-진화">3. 원석을 에이전트로 제련하다: 모델 학습의 진화</h2>

<h3 id="31-사전-학습-pre-training">3.1. 사전 학습 (Pre-training)</h3>

\[L_{CE} = -\sum_{i=1}^{N} \log P(x_i \mid x_{&lt;i}, \theta)\]

<p>수조 개의 토큰에 대해 이 손실 함수를 최소화하면, 모델은 문법, 논리, 상식을 가중치 속에 압축하게 된다.</p>

<h3 id="32-정렬-alignment-sft와-rlhf">3.2. 정렬 (Alignment): SFT와 RLHF</h3>

<p><strong>SFT:</strong> 전문가가 작성한 고품질 [질문-답변] 쌍으로 ‘대화하는 법’을 가르친다.</p>

<p><strong>DPO (Direct Preference Optimization):</strong></p>

\[L_{DPO} = -\log \sigma \left(\beta \log \frac{\pi_\theta(y_w \mid x)}{\pi_{ref}(y_w \mid x)} - \beta \log \frac{\pi_\theta(y_l \mid x)}{\pi_{ref}(y_l \mid x)}\right)\]

<hr />

<h2 id="4-거대화의-함정과-slm의-부상">4. 거대화의 함정과 SLM의 부상</h2>

<h3 id="41-스케일링-법칙">4.1. 스케일링 법칙</h3>

<p>모델 성능은 파라미터 수(N)와 학습 데이터 양(D)에 의해 예측 가능한 법칙을 따른다:</p>

\[L(N,D) \approx \frac{A}{N^\alpha} + \frac{B}{D^\beta}\]

<p>여기서 $L$은 손실(loss), $A$, $B$는 상수, $\alpha \approx 0.076$, $\beta \approx 0.095$이다. 모델을 키우면 성능은 올라가지만, 수확 체감(diminishing returns)이 존재한다. 파라미터를 10배 늘려도 성능 향상은 로그 스케일에 불과하다.</p>

<p>Chinchilla 연구는 <strong>최적의 N:D 비율</strong>이 존재함을 보였다. 같은 연산 예산이라면 모델을 무작정 키우는 것보다 데이터를 충분히 확보하는 것이 더 효율적이다. Gemma 4의 설계 철학은 이 원칙을 충실히 따른다.</p>

<h3 id="42-양자화-quantization-로컬-ai-시대의-열쇠">4.2. <a href="/concepts/quantization/">양자화 (Quantization)</a>: 로컬 AI 시대의 열쇠</h3>

<p>양자화는 모델의 가중치를 FP32/FP16에서 INT8/INT4로 낮추어 메모리와 연산량을 줄이는 기법이다:</p>

\[W_q = \text{round}\left(\frac{W}{S}\right) + Z\]

<p>여기서 $S$는 스케일 팩터, $Z$는 제로 포인트이다. 양자화의 도전 과제는 정밀도 손실을 최소화하면서 압축률을 극대화하는 것이다.</p>

<table>
  <thead>
    <tr>
      <th>기법</th>
      <th>타겟</th>
      <th>핵심 전략</th>
      <th>호환성</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GPTQ</td>
      <td>GPU</td>
      <td>열 단위 순차 보상 — Hessian 역행렬로 양자화 오차를 후속 열에 분산</td>
      <td>vLLM, TGI</td>
    </tr>
    <tr>
      <td>AWQ</td>
      <td>GPU</td>
      <td>활성화 기반 채널 보존 — 활성화 값이 큰 채널은 높은 정밀도 유지</td>
      <td>vLLM, TGI</td>
    </tr>
    <tr>
      <td>GGUF</td>
      <td>CPU+GPU</td>
      <td>혼합 정밀도 — 레이어별로 다른 비트 수 할당, CPU 오프로딩 지원</td>
      <td>llama.cpp, Ollama</td>
    </tr>
  </tbody>
</table>

<h3 id="43-지식-증류-knowledge-distillation">4.3. 지식 증류 (Knowledge Distillation)</h3>

<p>거대 모델(Teacher)의 지식을 소형 모델(Student)에 전이하는 기법이다:</p>

\[\mathcal{L}_{KD} = D_{KL}(P_{\text{teacher}} \| P_{\text{student}})\]

<p>Teacher의 소프트 확률 분포(soft label)를 Student가 모방하도록 학습시킨다. 하드 라벨(정답만 1, 나머지 0)과 달리, 소프트 라벨은 “정답이 아닌 토큰들 간의 상대적 확률”까지 전달하므로 더 풍부한 정보를 담고 있다.</p>

<p>Gemma 4가 Gemini의 핏줄을 이어받은 핵심 메커니즘이 바로 이것이다. Gemini의 방대한 파라미터에 압축된 세계 지식을, 증류를 통해 Gemma 4의 소형 아키텍처에 효율적으로 전이했다.</p>

<hr />

<h2 id="5-텍스트의-벽을-넘다-멀티모달-아키텍처">5. 텍스트의 벽을 넘다: 멀티모달 아키텍처</h2>

<p>현대 AI의 핵심 트렌드는 텍스트만이 아닌 이미지, 오디오, 비디오를 하나의 모델에서 통합 처리하는 것이다. Gemma 4는 각 모달리티별 전용 인코더를 두고, 이를 언어 모델의 임베딩 공간에 정렬(align)하는 구조를 채택했다.</p>

<h3 id="51-vision-encoder">5.1. Vision Encoder</h3>

<p>Gemma 4의 비전 인코더는 SigLIP 기반의 ViT(Vision Transformer) 아키텍처를 사용한다.</p>

<p><strong>처리 파이프라인:</strong></p>
<ol>
  <li>입력 이미지를 고정 크기 패치(예: 14×14 픽셀)로 분할</li>
  <li>각 패치를 선형 투영하여 토큰 시퀀스로 변환</li>
  <li>위치 임베딩을 추가하여 공간 정보 보존</li>
  <li>ViT 레이어를 통과시켜 시각적 특징 추출</li>
  <li>프로젝션 레이어를 통해 언어 모델의 임베딩 차원에 정렬</li>
</ol>

<p><strong>가변 종횡비 지원:</strong> Pan-and-Scan 방식으로 원본 이미지의 종횡비를 유지하면서 패치를 생성한다. 토큰 버짓은 70~1120개로 조절 가능하며, 이미지 해상도와 복잡도에 따라 동적으로 결정된다.</p>

<h3 id="52-audio-encoder">5.2. Audio Encoder</h3>

<p>소형 모델(E2B, E4B)은 USM-style conformer 아키텍처로 오디오를 네이티브 처리한다.</p>

<p><strong>Conformer 구조:</strong></p>
<ul>
  <li><strong>Convolution 모듈:</strong> 로컬 패턴(음소, 음절) 포착</li>
  <li><strong>Self-Attention 모듈:</strong> 글로벌 문맥(문장 구조, 억양) 파악</li>
  <li><strong>Feed-Forward 모듈:</strong> 비선형 변환</li>
</ul>

<p>오디오 입력은 Mel-spectrogram으로 변환된 후, conformer 레이어를 통과하여 텍스트 토큰과 동일한 임베딩 공간에 매핑된다. 이를 통해 음성 인식, 음성 번역, 오디오 이해가 단일 모델에서 가능해진다.</p>

<h3 id="53-모달리티-정렬-cross-modal-alignment">5.3. 모달리티 정렬 (Cross-Modal Alignment)</h3>

<p>각 인코더의 출력은 별도의 프로젝션 레이어를 거쳐 언어 모델의 디코더에 입력된다. 핵심은 <strong>소프트 토큰(soft token)</strong> 방식으로, 비전/오디오 특징을 언어 토큰과 동일한 시퀀스에 인터리빙하여 어텐션 메커니즘이 자연스럽게 크로스모달 관계를 학습하도록 한다.</p>

<hr />

<h2 id="6-gemma-4-해부-로컬-ai-생태계의-정점">6. Gemma 4 해부: 로컬 AI 생태계의 정점</h2>

<p>Gemma 4 패밀리는 용도와 하드웨어 제약에 따라 4가지 변형을 제공한다.</p>

<table>
  <thead>
    <tr>
      <th>모델</th>
      <th>파라미터</th>
      <th>컨텍스트</th>
      <th>특징</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>E2B</td>
      <td>2.3B effective</td>
      <td>128K</td>
      <td>온디바이스, 오디오 네이티브</td>
    </tr>
    <tr>
      <td>E4B</td>
      <td>4.5B effective</td>
      <td>128K</td>
      <td>온디바이스, 오디오 네이티브</td>
    </tr>
    <tr>
      <td>31B</td>
      <td>31B dense</td>
      <td>256K</td>
      <td>LMArena 1452, 최고 품질</td>
    </tr>
    <tr>
      <td>26B-A4B</td>
      <td>26B/4B active (MoE)</td>
      <td>256K</td>
      <td>LMArena 1441, 효율성 극대화</td>
    </tr>
  </tbody>
</table>

<h3 id="61-핵심-아키텍처-혁신">6.1. 핵심 아키텍처 혁신</h3>

<p><strong>Local-Global Hybrid Attention:</strong> 홀수 레이어는 <a href="/concepts/sliding-window-attention/">Sliding Window Attention</a>(윈도우 512)으로 로컬 문맥을, 짝수 레이어는 Full Attention으로 글로벌 문맥을 처리한다. 이를 통해 $O(N^2)$ 연산량을 실질적으로 $O(N \cdot W)$에 가깝게 줄이면서도 긴 문맥 이해 능력을 유지한다.</p>

<p><strong>Dual RoPE (Rotary Position Embedding):</strong> 로컬 어텐션과 글로벌 어텐션에 서로 다른 주파수의 RoPE를 적용하여, 각 레이어가 최적의 위치 인코딩을 사용하도록 한다.</p>

<p><strong>PLE (Per-Layer Embeddings):</strong> 기존 모델은 입력 임베딩을 한 번만 생성하지만, Gemma 4는 각 레이어마다 토큰 특화 잔차 신호를 주입한다. 깊은 레이어에서도 입력 토큰의 원본 정보가 희석되지 않는다.</p>

<p><strong>Shared KV Cache:</strong> MoE 모델에서 전문가(expert) 간 Key-Value 캐시를 공유하여 메모리 사용량을 대폭 절감한다. 26B-A4B 모델이 4B 활성 파라미터만으로 26B급 성능을 내는 핵심 비결이다.</p>

<p><strong>MoE (Mixture of Experts):</strong> 26B-A4B 모델은 총 26B 파라미터 중 입력 토큰마다 4B만 활성화하는 희소 구조를 사용한다. 라우터 네트워크가 각 토큰을 가장 적합한 전문가에게 배정하여, 연산 효율과 모델 용량을 동시에 확보한다.</p>

<h3 id="62-실전-배포-시나리오">6.2. 실전 배포 시나리오</h3>

<ul>
  <li><strong>E2B/E4B:</strong> 스마트폰, 엣지 디바이스에서 실시간 음성 비서, 이미지 캡셔닝</li>
  <li><strong>31B:</strong> 연구용 고품질 추론, 복잡한 코드 생성, 장문 분석</li>
  <li><strong>26B-A4B:</strong> RTX 3090/4090 단일 GPU에서 INT4 양자화로 구동 가능, 프로덕션 서빙에 최적</li>
</ul>

<hr />

<h2 id="7-결론-오픈소스-모델이-그려갈-미래">7. 결론: 오픈소스 모델이 그려갈 미래</h2>

<p>Gemma 4는 단순한 모델 릴리스를 넘어, AI 생태계의 패러다임 전환을 상징한다.</p>

<p><strong>독점에서 개방으로:</strong> GPT-4, Claude 같은 독점 API에 의존하던 시대에서, Apache 2.0 라이선스의 오픈소스 모델이 동등한 성능을 제공하는 시대로 전환되고 있다. 이는 개인 개발자와 소규모 팀에게 AI 주도권을 돌려준다.</p>

<p><strong>클라우드에서 로컬로:</strong> <a href="/concepts/quantization/">양자화</a> 기술(GPTQ, AWQ, GGUF)과 MoE 아키텍처의 결합으로, 소비자급 GPU에서도 프론티어급 지능을 구동할 수 있게 되었다. RTX 3090 한 장으로 26B 모델을 실시간 추론하는 것이 현실이 되었다.</p>

<p><strong>단일 모달에서 멀티모달로:</strong> 텍스트만 처리하던 LLM이 이미지, 오디오, 비디오를 통합 이해하는 범용 AI로 진화하고 있다. Gemma 4의 네이티브 멀티모달 아키텍처는 이 방향의 최전선에 있다.</p>

<p><strong>앞으로의 과제:</strong> 환각(hallucination) 감소, 추론 능력 강화, 에이전트 시스템과의 통합이 다음 단계의 핵심 연구 주제가 될 것이다. Gemma 4가 제공하는 Function Calling 기능은 이미 에이전트 생태계로의 진입을 예고하고 있다.</p>

<hr />

<p><strong>관련 개념 포스트:</strong></p>
<ul>
  <li><a href="/concepts/tokenization/">토큰화 (Tokenization)</a></li>
  <li><a href="/concepts/embedding/">임베딩 (Embedding)</a></li>
  <li><a href="/concepts/attention/">어텐션 (Attention)</a></li>
  <li><a href="/concepts/transformer/">트랜스포머 (Transformer)</a></li>
  <li><a href="/concepts/quantization/">양자화 (Quantization)</a></li>
  <li><a href="/concepts/sliding-window-attention/">Sliding Window Attention</a></li>
</ul>]]></content><author><name></name></author><category term="study" /><category term="LLM" /><category term="Gemma4" /><category term="LLM" /><category term="SLM" /><category term="Transformer" /><category term="멀티모달" /><category term="양자화" /><category term="어텐션" /><summary type="html"><![CDATA[Gemma 4에 대한 이해를 위해 SLM/LLM의 시작점부터 살펴보며 해석을 수행한다.]]></summary></entry></feed>