<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_brojean.log</title>
        <link>https://velog.io/</link>
        <description>AI로 유용한 서비스 개발을 꿈꾸는 A린이</description>
        <lastBuildDate>Sun, 15 Mar 2026 09:50:30 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. dev_brojean.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_brojean" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[논문 리뷰] SimulSpeech: End-to-End Simultaneous Speech to Text Translation]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SimulSpeech-End-to-End-Simultaneous-Speech-to-Text-Translation</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SimulSpeech-End-to-End-Simultaneous-Speech-to-Text-Translation</guid>
            <pubDate>Sun, 15 Mar 2026 09:50:30 GMT</pubDate>
            <description><![CDATA[<h3 id="simulspeech-end-to-end-simultaneous-speech-to-text-translationhttpsaclanthologyorg2020acl-main350pdf">SimulSpeech: End-to-End Simultaneous Speech to Text Translation(<a href="https://aclanthology.org/2020.acl-main.350.pdf">https://aclanthology.org/2020.acl-main.350.pdf</a>)</h3>
<h4 id="중간-단계를-없애고-음성에서-번역문을-직접--더-빠르고-더-정확한-동시-음성-번역">중간 단계를 없애고 음성에서 번역문을 직접 — 더 빠르고 더 정확한 동시 음성 번역</h4>
<blockquote>
<p>음성 인식 → 번역이라는 두 단계를 하나로 합치고,<br><strong>CTC 분절기 + Wait-k + 두 가지 지식 증류</strong>로 오류 누적을 없앤 종단간 동시 음성 번역 시스템.<br>ACL 2020 | Yi Ren<em>, Jinglin Liu</em>, Xu Tan* et al. (Zhejiang University / Microsoft Research)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 동시 통역 시스템의 오래된 구조적 문제를 정면으로 파고듭니다.</p>
<p><strong>&quot;왜 두 개의 모델을 이어 붙여야만 할까?&quot;</strong></p>
<p>기존의 동시 음성 번역 시스템은 두 단계로 작동합니다. 먼저 실시간 음성 인식기(ASR)가 소리를 텍스트로 바꿉니다. 그다음 실시간 번역기(NMT)가 그 텍스트를 다른 언어로 바꿉니다. 이 방식에는 치명적인 단점이 있습니다. 앞 단계에서 생긴 오류가 그대로 다음 단계로 전달됩니다. 두 모델을 거치므로 지연도 두 배로 쌓입니다.</p>
<p>이 논문은 <strong>음성을 텍스트로 바꾸는 중간 단계를 완전히 없애고</strong>, 소리에서 번역문을 직접 만들어내는 단일 모델 SimulSpeech를 제안합니다. 그리고 이 어려운 목표를 달성하기 위해 두 가지 지식 증류 기법을 새롭게 설계했습니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 동시 번역의 기술적 맥락을 살펴봅니다.</p>
<h3 id="동시-번역의-핵심-딜레마">동시 번역의 핵심 딜레마</h3>
<p>동시 번역에서 속도와 정확도는 시소 관계입니다.</p>
<table>
<thead>
<tr>
<th>전략</th>
<th>번역 시작 시점</th>
<th>정확도</th>
<th>지연</th>
</tr>
</thead>
<tbody><tr>
<td><strong>빠르게 시작</strong></td>
<td>단어 1~2개 후</td>
<td>문맥 부족 → 오역 위험</td>
<td>짧음</td>
</tr>
<tr>
<td><strong>느리게 시작</strong></td>
<td>문장 전체 후</td>
<td>높음</td>
<td>길어 사용자 불만</td>
</tr>
<tr>
<td><strong>Wait-k (균형점)</strong></td>
<td>k개 단어 후</td>
<td>k에 따라 조절</td>
<td>k에 따라 조절</td>
</tr>
</tbody></table>
<h3 id="ctc-분절의-핵심-도구">CTC: 분절의 핵심 도구</h3>
<p>SimulSpeech의 분절기는 CTC(Connectionist Temporal Classification) 손실을 기반으로 작동합니다. 음성 프레임 수준의 출력을 텍스트 시퀀스로 매핑합니다. 여러 CTC 경로가 같은 텍스트 시퀀스에 대응하는 다대일 구조입니다.</p>
<p>$$P(y|x) = \sum_{z \in \phi(y)} P(z|x)$$</p>
<p>예시로, &quot;HELLO&quot;에 해당하는 CTC 경로는 &quot;HHE∅L∅LOO&quot;와 &quot;∅HHEEL∅LO&quot; 등 여러 가지가 될 수 있습니다. 이 유연성 덕분에 프레임 수준의 정확한 레이블 없이도 단어 경계를 학습할 수 있습니다.</p>
<h3 id="wait-k-전략">Wait-k 전략</h3>
<p>$$P(y|x; k; \theta) = \prod_{t=1}^{T_y} P(y_t | y_{&lt;t},\ x_{&lt;t+k};\ \theta)$$</p>
<p>$t$번째 번역 단어를 생성할 때 소스 세그먼트 $t+k-1$번째까지만 볼 수 있습니다. $k$가 클수록 더 많은 문맥을 보므로 정확도는 올라가지만 지연이 길어집니다.</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;2단계 캐스케이드 방식의 오류 누적과 이중 지연&quot;</strong> 입니다.</p>
<h3 id="캐스케이드-방식의-두-가지-구조적-문제">캐스케이드 방식의 두 가지 구조적 문제</h3>
<table>
<thead>
<tr>
<th>문제</th>
<th>설명</th>
<th>실제 예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>오류 누적</strong></td>
<td>ASR이 틀린 단어를 NMT에 전달</td>
<td>&quot;classic&quot;을 &quot;class sake&quot;로 인식 → &quot;clase sake&quot;로 번역</td>
</tr>
<tr>
<td><strong>이중 지연</strong></td>
<td>ASR의 wait-k + NMT의 wait-k가 합산</td>
<td>ASR wait-1 + NMT wait-3 = 사실상 wait-4 수준의 지연</td>
</tr>
</tbody></table>
<h3 id="논문의-핵심-사례-figure-5">논문의 핵심 사례 (Figure 5)</h3>
<p>논문이 직접 제시한 실제 번역 예시입니다.</p>
<table>
<thead>
<tr>
<th>시스템</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td><strong>원문</strong></td>
<td>&quot;the first on here is the classic apple.&quot;</td>
</tr>
<tr>
<td><strong>ASR (wait-1) 오인식</strong></td>
<td>&quot;the first on here is the <strong>class sake</strong> apple.&quot;</td>
</tr>
<tr>
<td><strong>캐스케이드 번역 결과</strong></td>
<td>&quot;pero la primera vez es una manzana motivo de <strong>clase</strong>.&quot; ❌</td>
</tr>
<tr>
<td><strong>SimulSpeech (wait-3) 결과</strong></td>
<td>&quot;la primera es una manzana <strong>clásica</strong>.&quot; ✅</td>
</tr>
</tbody></table>
<blockquote>
<p>&quot;classic&quot; 한 단어의 오인식이 전체 번역 품질을 망쳤습니다. SimulSpeech는 중간 텍스트를 거치지 않으므로 이 문제가 발생하지 않습니다.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>SimulSpeech는 <strong>음성 인코더 + 음성 분절기 + 텍스트 디코더</strong> 세 모듈로 구성됩니다.</p>
<h3 id="전체-작동-흐름">전체 작동 흐름</h3>
<ol>
<li><strong>Pre-Net (특징 추출):</strong> 오디오 파형을 멜 스펙트로그램으로 변환합니다. 3층 합성곱 네트워크가 음향 특징을 추출합니다.</li>
<li><strong>인코더 (마스크 자기 어텐션):</strong> 미래 프레임을 보지 못하게 마스킹한 트랜스포머 인코더가 은닉 상태를 생성합니다.</li>
<li><strong>음성 분절기 (CTC):</strong> 인코더 출력을 받아 단어 경계를 감지합니다. 공백 문자가 예측되는 순간이 단어 하나의 끝입니다.</li>
<li><strong>디코더 (Wait-k 어텐션):</strong> 분절기가 k개의 단어 경계를 감지하면 번역 단어를 하나씩 출력하기 시작합니다.</li>
</ol>
<h3 id="wait-k-작동-예시-k2일-때">Wait-k 작동 예시: $k=2$일 때</h3>
<table>
<thead>
<tr>
<th>시간</th>
<th>분절기 감지</th>
<th>디코더 행동</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;I&quot; 입력</td>
<td>1번째 단어 경계</td>
<td>대기</td>
</tr>
<tr>
<td>&quot;am&quot; 입력</td>
<td>2번째 단어 경계</td>
<td><strong>&quot;나는&quot; 출력</strong></td>
</tr>
<tr>
<td>&quot;a&quot; 입력</td>
<td>3번째 단어 경계</td>
<td>다음 번역 단어 출력</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>이후 매 세그먼트마다 즉시 출력</td>
</tr>
</tbody></table>
<h3 id="핵심-혁신-두-가지-지식-증류">핵심 혁신: 두 가지 지식 증류</h3>
<p>End-to-End 동시 번역은 음성 인식보다 훨씬 어렵습니다. 음성-번역문 사이의 정렬을 처음부터 학습해야 하기 때문입니다. 저자들은 이미 학습된 두 전문가 모델의 지식을 SimulSpeech에 주입하는 방식으로 이 문제를 해결했습니다.</p>
<h4 id="1-어텐션-수준-지식-증류-attention-level-kd">1) 어텐션 수준 지식 증류 (Attention-Level KD)</h4>
<p><strong>직관: 두 전문가의 지식을 곱해서 모범 답안 만들기</strong></p>
<ul>
<li>전문가 A (ASR): 음성 ↔ 원문 텍스트의 정렬을 압니다 ($A_{Tsrc \times Ssrc}$)</li>
<li>전문가 B (NMT): 원문 텍스트 ↔ 번역 텍스트의 정렬을 압니다 ($A_{Ttgt \times Tsrc}$)</li>
<li>두 행렬을 곱하면 음성 ↔ 번역 텍스트의 이상적 정렬이 나옵니다</li>
</ul>
<p>$$A_{Ttgt \times Ssrc}^{ideal} = A_{Ttgt \times Tsrc} \times A_{Tsrc \times Ssrc}$$</p>
<p>이 이상적 행렬을 0.05 임계값으로 이진화(Binarization)한 뒤, SimulSpeech의 어텐션이 이를 모방하도록 학습시킵니다.</p>
<p>$$L_{att_kd} = -B(A_{Ttgt \times Tsrc} \times A_{Tsrc \times Ssrc}) \times A_{SimulST}^{Ttgt \times Ssrc}$$</p>
<blockquote>
<p><strong>비유: 두 전문가의 답안지를 합치기</strong><br>음성 전문가는 &quot;음성의 2<del>3초 구간이 &#39;apple&#39;이다&quot;라고 알고, 번역 전문가는 &quot;&#39;apple&#39;이 &#39;manzana&#39;에 해당한다&quot;라고 압니다. 두 답안을 곱하면 &quot;음성의 2</del>3초 구간이 &#39;manzana&#39;에 해당한다&quot;는 완벽한 모범 답안이 됩니다.</p>
</blockquote>
<h4 id="2-데이터-수준-지식-증류-data-level-kd">2) 데이터 수준 지식 증류 (Data-Level KD)</h4>
<p>전체 문장을 다 보고 번역하는 <strong>오프라인 NMT 교사 모델</strong>이 만들어낸 번역문으로 학습 데이터를 교체합니다.</p>
<p>$$L_{data_kd} = -\sum_{(x, y&#39;) \in (X \times Y&#39;_{tgt})} \log P(y&#39;|x)$$</p>
<p>실제 사람이 작성한 번역문보다 교사 NMT가 생성한 번역문이 SimulSpeech가 학습하기에 더 단순하고 일관된 분포를 가집니다. 학습 최적화가 쉬워집니다.</p>
<h3 id="최종-손실-함수">최종 손실 함수</h3>
<p>$$L = \lambda_1 L_{ctc} + \lambda_2 L_{att_kd} + \lambda_3 L_{data_kd}$$</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>값</th>
</tr>
</thead>
<tbody><tr>
<td>$\lambda_1$ (CTC)</td>
<td>1.0</td>
</tr>
<tr>
<td>$\lambda_2$ (어텐션 KD)</td>
<td>0.1</td>
</tr>
<tr>
<td>$\lambda_3$ (데이터 KD)</td>
<td>1.0</td>
</tr>
</tbody></table>
<hr>
<h3 id="📊-figure-1--wait-k-동시-번역-전략-다이어그램">📊 Figure 1 — Wait-k 동시 번역 전략 다이어그램</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/b3ecf666-e550-49b3-b8ab-29e7e22fd986/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> &quot;How is the weather today&quot;라는 영어 소스 오디오가 시간 순서로 들어올 때, $k=2$ 설정 하에서 소스 세그먼트 읽기(Listen)와 번역 단어 쓰기(Write)가 어떻게 교차하는지 보여줍니다. 처음 2개 세그먼트를 읽은 뒤 첫 번째 번역 단어를 쓰고, 이후 세그먼트 하나가 들어올 때마다 번역 단어 하나를 씁니다.</li>
<li><strong>핵심 메시지:</strong> Wait-k에서 $k$는 &quot;번역을 시작하기 전 미리 들을 세그먼트 수&quot;입니다. 소스 세그먼트가 고갈되면 나머지는 전체 문장 번역으로 자연스럽게 전환됩니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>그림에서 Listen과 Write가 교차하는 패턴이 동시통역사의 작업 방식과 정확히 일치합니다. 전문 통역사도 &quot;2~3단어를 먼저 듣고 → 번역 시작 → 계속 들으면서 번역 지속&quot;이라는 리듬으로 작업합니다. Wait-k는 이 인간의 전략을 수식으로 공식화한 것입니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--simulspeech-모델-구조-및-학습-파이프라인">📊 Figure 2 — SimulSpeech 모델 구조 및 학습 파이프라인</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/91326a65-6755-41d6-bff4-7c9d83f2825a/image.png" alt=""></p>
<ul>
<li><strong>(a) 모델 구조:</strong> Pre-Net → 마스크 자기 어텐션 인코더 N층 → 음성 분절기(소프트맥스 선형) → Wait-k 디코더 어텐션 N층 → 출력 텍스트. 인코더와 디코더 모두 기본 트랜스포머 구조를 따릅니다.</li>
<li><strong>(b) 학습 파이프라인:</strong> 보조 ASR 태스크(인코더 공유), 보조 NMT 태스크(디코더 공유), 오프라인 NMT 교사 모델, 데이터 수준 KD, 어텐션 수준 KD가 SimulSpeech 본 모델(보라색 박스)을 감싸는 구조.</li>
<li><strong>핵심 메시지:</strong> SimulSpeech 자체는 보라색 박스 하나지만, 학습 시에는 ASR과 NMT 보조 태스크가 어텐션 행렬 지식을 제공합니다. 추론 시에는 보조 태스크 없이 본 모델만 작동합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>보조 ASR과 보조 NMT가 인코더/디코더를 SimulSpeech와 <strong>공유</strong>한다는 점이 핵심입니다. 공유 덕분에 어텐션 행렬의 지식이 자연스럽게 SimulSpeech 파라미터에 스며듭니다. 별도의 교사 모델을 따로 훈련할 필요가 없습니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-3--어텐션-수준-지식-증류-상세-다이어그램">📊 Figure 3 — 어텐션 수준 지식 증류 상세 다이어그램</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/c5a8ad65-a212-498c-8c88-5f33c229e072/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> ASR 어텐션 행렬($T_{src} \times S_{src}$)과 NMT 어텐션 행렬($T_{tgt} \times T_{src}$)을 행렬 곱하면 S2T 어텐션 교사 행렬($T_{tgt} \times S_{src}$)이 만들어집니다. 이를 이진화한 뒤 SimulSpeech가 예측한 어텐션과 비교해 Binarization Loss를 계산합니다.</li>
<li><strong>핵심 메시지:</strong> 음성 길이($S_{src}$), 소스 텍스트 길이($T_{src}$), 번역 텍스트 길이($T_{tgt}$) 세 차원에서 두 행렬을 곱해 차원이 맞는 음성-번역 정렬 행렬을 만드는 과정입니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>이진화(Binarization) 임계값 0.05는 어텐션 행렬에서 노이즈를 제거하고 명확한 정렬만 남기기 위한 것입니다. 부드러운 어텐션보다 날카로운 이진 신호가 SimulSpeech 학습을 안정적으로 가이드합니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-4--번역-품질bleu-vs-지연-시간apal-트레이드오프">📊 Figure 4 — 번역 품질(BLEU) vs 지연 시간(AP/AL) 트레이드오프</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/4c0e4afb-c34b-4f0a-b74e-af284fdb82e6/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> En→Es 데이터셋에서 $k=1,3,5,7,9$와 $k=\infty$(오프라인) 각각의 BLEU 점수와 AP(Average Proportion)/AL(Average Lagging) 지연 값을 SimulSpeech와 train-full test-k 두 곡선으로 비교합니다.</li>
<li><strong>핵심 메시지:</strong> 동일 지연 수준에서 SimulSpeech가 항상 train-full test-k보다 높은 BLEU를 기록합니다. 훈련 시부터 Wait-k 방식으로 학습한 것이 테스트 시 Wait-k를 적용하는 것보다 일관되게 우수합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>곡선이 오른쪽 위로 갈수록(k가 커질수록) BLEU가 높아지고 지연도 길어집니다. 두 곡선 간의 수직 격차가 SimulSpeech의 지식 증류 효과를 시각적으로 증명합니다. 같은 지연이면 SimulSpeech가 항상 더 정확합니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-5--오류-누적-사례-분석">📊 Figure 5 — 오류 누적 사례 분석</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/dbbe9b7e-6aef-46d0-85f7-64e0cf3df119/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> &quot;classic apple&quot;이라는 영어 표현에서 ASR(wait-1)이 &quot;class sake apple&quot;로 오인식하고, 이 오류가 NMT 번역 결과까지 망치는 캐스케이드 오류 전파 과정. SimulSpeech(wait-3)는 &quot;manzana clásica(클래식 사과)&quot;로 올바르게 번역합니다.</li>
<li><strong>핵심 메시지:</strong> 동일한 지연(ASR wait-1 + NMT wait-3 = SimulSpeech wait-3)에서 캐스케이드 방식은 오인식 하나로 전체 번역이 무너지지만, SimulSpeech는 음성-번역 직접 정렬로 이 문제를 피합니다.</li>
</ul>
<hr>
<h3 id="📊-figure-6--simulspeech-vs-캐스케이드-bleu-지연-비교">📊 Figure 6 — SimulSpeech vs 캐스케이드 BLEU-지연 비교</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/f58f5aa7-c680-4f46-800d-cdcdf9d67d62/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> AL(Average Lagging)을 X축, BLEU를 Y축으로 SimulSpeech와 캐스케이드 두 곡선을 비교합니다.</li>
<li><strong>핵심 메시지:</strong> SimulSpeech wait-3이 캐스케이드 wait-5와 동일한 BLEU를 달성합니다. 즉 두 세그먼트 더 빨리 시작하면서 같은 번역 품질을 냅니다.</li>
</ul>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<h3 id="실험-설정">실험 설정</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>MuST-C En→Es (496시간, 229,703문장), En→De (400시간, 265,625문장)</td>
</tr>
<tr>
<td><strong>모델 구조</strong></td>
<td>Transformer (히든 384, 헤드 4, 인코더 6층, 디코더 4층)</td>
</tr>
<tr>
<td><strong>음향 입력</strong></td>
<td>멜 스펙트로그램 (50ms 프레임, 12.5ms 홉)</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>BLEU (번역 품질), AP / AL (지연 시간)</td>
</tr>
<tr>
<td><strong>학습 환경</strong></td>
<td>NVIDIA Tesla V100 × 2, 배치 64문장</td>
</tr>
</tbody></table>
<h3 id="번역-품질-결과-table-2-bleu-점수">번역 품질 결과 (Table 2: BLEU 점수)</h3>
<table>
<thead>
<tr>
<th>$k$</th>
<th>1</th>
<th>3</th>
<th>5</th>
<th>7</th>
<th>9</th>
<th>∞ (오프라인)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>En→Es SimulSpeech</strong></td>
<td>15.02</td>
<td>19.92</td>
<td>21.58</td>
<td>22.42</td>
<td>22.49</td>
<td>22.72</td>
</tr>
<tr>
<td>En→Es FS(오프라인 학습+Wait-k 테스트)</td>
<td>3.25</td>
<td>7.18</td>
<td>10.52</td>
<td>13.33</td>
<td>15.32</td>
<td>22.72</td>
</tr>
<tr>
<td><strong>En→De SimulSpeech</strong></td>
<td>10.73</td>
<td>15.52</td>
<td>16.90</td>
<td>17.46</td>
<td>17.87</td>
<td>18.29</td>
</tr>
</tbody></table>
<h3 id="캐스케이드-vs-simulspeech-비교-table-3-en→es">캐스케이드 vs SimulSpeech 비교 (Table 3: En→Es)</h3>
<table>
<thead>
<tr>
<th>$k$</th>
<th>Cascaded</th>
<th>SimulSpeech</th>
<th>우위</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>12.77</td>
<td><strong>15.02</strong></td>
<td>SimulSpeech +2.25 ✅</td>
</tr>
<tr>
<td>3</td>
<td>16.91</td>
<td><strong>19.92</strong></td>
<td>SimulSpeech +3.01 ✅</td>
</tr>
<tr>
<td>5</td>
<td>19.66</td>
<td><strong>21.58</strong></td>
<td>SimulSpeech +1.92 ✅</td>
</tr>
<tr>
<td>7</td>
<td>21.05</td>
<td><strong>22.42</strong></td>
<td>SimulSpeech +1.37 ✅</td>
</tr>
<tr>
<td>9</td>
<td>23.43</td>
<td>22.49</td>
<td>Cascaded 우위</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>실시간 번역에서 중요한 $k&lt;9$ 구간에서는 SimulSpeech가 캐스케이드를 일관되게 앞섭니다. Figure 6 기준으로 <strong>SimulSpeech wait-3 ≈ Cascaded wait-5</strong> 입니다. 두 세그먼트 덜 기다리면서 같은 품질을 냅니다.</p>
</blockquote>
<h3 id="절제-실험-table-4-각-기법의-기여도">절제 실험 (Table 4: 각 기법의 기여도)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>$k=1$</th>
<th>$k=5$</th>
<th>$k=9$</th>
</tr>
</thead>
<tbody><tr>
<td>Naive S2T</td>
<td>9.02</td>
<td>14.90</td>
<td>15.90</td>
</tr>
<tr>
<td>+ 보조 태스크</td>
<td>12.98</td>
<td>19.41</td>
<td>20.39</td>
</tr>
<tr>
<td>+ 보조 + Data KD</td>
<td>13.77</td>
<td>20.98</td>
<td>21.52</td>
</tr>
<tr>
<td>+ 보조 + Attn KD</td>
<td>13.74</td>
<td>20.64</td>
<td>20.90</td>
</tr>
<tr>
<td><strong>+ 보조 + Data KD + Attn KD</strong></td>
<td><strong>15.02</strong></td>
<td><strong>21.58</strong></td>
<td><strong>22.49</strong></td>
</tr>
</tbody></table>
<blockquote>
<p>두 지식 증류 기법이 각각 독립적으로도 효과적이며, 함께 쓸 때 최고 성능을 냅니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>오류 누적 해소</strong> — ASR 오인식이 번역에 전파되는 캐스케이드 문제가 구조적으로 사라집니다.</li>
<li><strong>이중 지연 제거</strong> — 단일 모델이므로 Wait-k가 한 번만 적용됩니다. 같은 품질에서 더 빠릅니다.</li>
<li><strong>어텐션 KD의 우아함</strong> — 두 전문가 모델의 어텐션 행렬 곱으로 음성-번역 정렬 모범 답안을 자동 생성합니다. 별도의 음성-번역 정렬 데이터가 필요 없습니다.</li>
<li><strong>단일 파라미터 최적화</strong> — 모든 구성 요소가 동시에 학습되므로 전체 목표에 최적화됩니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>고정된 Wait-k</strong> — $k=3$으로 설정하면 단순한 단어도, 복잡한 전문 용어도 무조건 3세그먼트를 기다립니다. 문맥 난이도에 따른 유연성이 없습니다.</li>
<li><strong>분절기의 취약성</strong> — 화자가 기침하거나 &quot;어...&quot; 하고 머뭇거리면 분절기가 이를 단어 경계로 착각할 수 있습니다. 엉뚱한 타이밍에 번역이 시작될 위험이 있습니다.</li>
<li><strong>큰 k에서 캐스케이드에 열세</strong> — $k \geq 9$ 구간에서는 캐스케이드가 앞섭니다. 지연이 충분히 허용되는 환경에서는 캐스케이드가 나을 수 있습니다.</li>
<li><strong>데이터 요구량</strong> — 학습 데이터가 (소스 음성, 소스 텍스트, 번역 텍스트) 세 가지 쌍으로 구성돼야 합니다. 데이터 구축 비용이 높습니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<ol>
<li><strong>적응형 Wait-k</strong> — 인식의 불확실성이 낮으면 바로 번역하고, 높으면 더 기다리는 동적 정책으로 발전시킵니다.</li>
<li><strong>분절기 강화</strong> — 묵음·잡음·머뭇거림을 단어 경계와 명확히 구분하는 더 정교한 분절 모듈이 필요합니다.</li>
<li><strong>음성→음성 번역</strong> — 저자들이 직접 언급한 향후 방향입니다. 타깃 언어를 텍스트가 아닌 음성으로 생성하는 음성→음성 동시 번역으로 확장합니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>&quot;두 개의 전문가 어텐션 행렬을 곱하면 그 중간 다리를 건너뛴 정렬이 만들어진다&quot;는 아이디어가 놀라웠습니다. 수학적으로 당연한 행렬 곱이지만, 이것을 지식 증류의 모범 답안으로 활용한다는 발상이 매우 창의적입니다. 복잡한 음성-번역 정렬을 처음부터 학습하지 않아도 된다는 실용적 우아함이 인상 깊었습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>&quot;오류 누적을 줄이려면 각 모듈의 정확도를 높여야 한다&quot;고 생각했습니다.</p>
<blockquote>
<p><strong>하지만 SimulSpeech는 구조 자체를 바꿔 문제를 해결했습니다.</strong> 오류 누적이 발생하는 중간 단계를 없애버리니 아무리 각 모듈이 뛰어나도 피할 수 없는 구조적 문제가 사라졌습니다. 성능 개선보다 구조적 재설계가 더 근본적인 해법이 될 수 있음을 배웠습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>국제 학술 컨퍼런스 실시간 자막 서비스에 SimulSpeech를 적용하면 흥미로울 것 같습니다. 특히 학술 발표는 단어 경계가 비교적 명확하고 발화 속도가 일정해서 분절기의 취약성이 줄어듭니다. wait-3 수준에서 캐스케이드 wait-5와 동등한 품질이 나오므로, 청중이 느끼는 자막 지연이 크게 줄어들 것 같습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>캐스케이드 ASR+NMT의 오류 누적과 이중 지연 — 두 모델이 분리되어 최적화되지 않음</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>CTC 분절기로 음성 세그먼트 감지 + Wait-k 디코더로 실시간 번역 + 어텐션/데이터 이중 지식 증류</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>$k&lt;9$ 동시 번역 환경에서 캐스케이드 대비 일관된 BLEU 향상, SimulSpeech wait-3 ≈ Cascaded wait-5</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>ASR 어텐션 × NMT 어텐션 = S2T 정렬 모범 답안이라는 수학적으로 우아한 지식 증류 설계</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>고정 Wait-k의 유연성 부재, 분절기의 잡음 취약성, $k \geq 9$에서 캐스케이드에 열세</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>적응형 Wait-k 정책, 강건한 분절기, 음성→음성 동시 번역</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>SimulSpeech는 ASR→NMT의 오류 누적 구조를 CTC 분절기와 Wait-k 디코더로 하나로 합치고, 두 전문가 어텐션의 행렬 곱을 모범 답안으로 삼는 이중 지식 증류로 학습을 안정화해, 같은 지연에서 캐스케이드를 능가하는 종단간 동시 음성 번역 시스템이다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Whisper: Robust Speech Recognition via Large-Scale Weak Supervision]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Whisper-Robust-Speech-Recognition-via-Large-Scale-Weak-Supervision</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Whisper-Robust-Speech-Recognition-via-Large-Scale-Weak-Supervision</guid>
            <pubDate>Sat, 14 Mar 2026 11:00:27 GMT</pubDate>
            <description><![CDATA[<h3 id="whisper-robust-speech-recognition-via-large-scale-weak-supervisionhttpsarxivorgpdf221204356">Whisper: Robust Speech Recognition via Large-Scale Weak Supervision(<a href="https://arxiv.org/pdf/2212.04356">https://arxiv.org/pdf/2212.04356</a>)</h3>
<h4 id="680000시간의-지저분한-인터넷-데이터로-만든-만능-음성-인식--추가-학습-없이-사람-수준에-도달하다">680,000시간의 지저분한 인터넷 데이터로 만든 만능 음성 인식 — 추가 학습 없이 사람 수준에 도달하다</h4>
<blockquote>
<p>깨끗한 데이터 1,000시간 대신 지저분한 인터넷 데이터 <strong>68만 시간</strong>을 쏟아부어,<br>어떤 환경에서도 추가 학습(Fine-tuning) 없이 바로 작동하는 다국어 음성 인식 시스템.<br>ICML 2023 | Alec Radford<em>, Jong Wook Kim</em> et al. (OpenAI)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 음성 인식 분야에서 오랫동안 묻혀 있던 질문을 꺼냅니다.</p>
<p><strong>&quot;LibriSpeech에서 사람을 뛰어넘는 모델이, 왜 실제 세상에서는 엉망이 될까?&quot;</strong></p>
<p>2015년 Deep Speech 2는 LibriSpeech test-clean에서 사람 수준의 WER을 달성했습니다. 그런데 7년 후에도 여전히 시끄러운 환경이나 사투리가 섞인 음성 앞에서 기계는 사람보다 약 2배 더 많은 오류를 냅니다. 이 논문은 그 이유를 정확히 짚습니다. <strong>훈련과 평가가 같은 데이터 분포 안에서만 이루어지기 때문입니다.</strong> 사람은 처음 보는 환경에서도 잘 인식하는데, 기계는 자기가 공부한 데이터와 조금만 달라져도 무너집니다.</p>
<p>Whisper는 이 문제를 해결하기 위해 완전히 다른 방향을 선택했습니다. 깨끗한 데이터를 만드는 데 공을 들이는 대신, 인터넷의 지저분하고 오류가 섞인 오디오-텍스트 쌍을 <strong>68만 시간</strong> 규모로 쏟아부었습니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이 방향이 혁신적인지 배경을 살펴봅니다.</p>
<h3 id="음성-인식의-두-가지-주류-방식">음성 인식의 두 가지 주류 방식</h3>
<table>
<thead>
<tr>
<th>방식</th>
<th>대표 모델</th>
<th>장점</th>
<th>치명적 한계</th>
</tr>
</thead>
<tbody><tr>
<td><strong>비지도 사전학습</strong></td>
<td>wav2vec 2.0</td>
<td>레이블 없이 100만 시간 학습 가능</td>
<td>디코더가 없어 Fine-tuning이 반드시 필요</td>
</tr>
<tr>
<td><strong>지도 학습</strong></td>
<td>기존 ASR 시스템</td>
<td>정확도 높음</td>
<td>깨끗한 데이터 부족, 분포 밖 성능 급락</td>
</tr>
</tbody></table>
<h3 id="비지도-사전학습의-아킬레스건">비지도 사전학습의 아킬레스건</h3>
<p>wav2vec 2.0 같은 비지도 모델은 인코더 학습에는 탁월합니다. 하지만 그 결과를 실제 텍스트로 변환하려면 <strong>Fine-tuning이라는 추가 단계</strong>가 꼭 필요합니다. 그리고 Fine-tuning 과정에서 또 다른 문제가 생깁니다.</p>
<blockquote>
<p>Fine-tuning된 모델은 특정 데이터셋의 <strong>버릇(spurious patterns)</strong> 을 학습합니다. LibriSpeech에서 Fine-tuning하면 LibriSpeech 스타일에 과적합되고, 다른 환경에서 성능이 뚝 떨어집니다.</p>
</blockquote>
<p>이것은 비단 음성 인식만의 문제가 아닙니다. 컴퓨터 비전에서도 동일한 현상이 관찰됐습니다. ImageNet에서 Fine-tuning한 모델이 ImageNet에서 9.2% 성능이 오르면서 동시에 다른 7개 데이터셋에서 평균 성능은 전혀 오르지 않는 현상이 확인된 바 있습니다.</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;현재 음성 인식 벤치마크의 &#39;초인간적 성능&#39;은 착시다&quot;</strong> 입니다.</p>
<h3 id="사람-vs-기계--공정하지-않은-비교">사람 vs 기계 — 공정하지 않은 비교</h3>
<table>
<thead>
<tr>
<th>평가 대상</th>
<th>학습 조건</th>
<th>실제 측정하는 것</th>
</tr>
</thead>
<tbody><tr>
<td><strong>사람</strong></td>
<td>특정 데이터셋 학습 없음</td>
<td><strong>분포 밖(OOD) 일반화 능력</strong></td>
</tr>
<tr>
<td><strong>기계 (Fine-tuned)</strong></td>
<td>해당 데이터셋으로 충분히 학습</td>
<td><strong>분포 내(In-distribution) 암기 능력</strong></td>
</tr>
</tbody></table>
<p>같은 테스트를 치르지만 서로 다른 능력을 재고 있습니다. LibriSpeech에서 WER 1.4%를 달성한 모델이 다른 환경에서는 사람보다 2배 더 틀리는 이유가 여기 있습니다.</p>
<h3 id="기존-데이터의-규모-한계">기존 데이터의 규모 한계</h3>
<table>
<thead>
<tr>
<th>데이터 유형</th>
<th>규모</th>
</tr>
</thead>
<tbody><tr>
<td>학술 지도 학습 데이터 (평균)</td>
<td>~1,000시간</td>
</tr>
<tr>
<td>SpeechStew (7개 데이터셋 합산)</td>
<td>5,140시간</td>
</tr>
<tr>
<td>비지도 학습 (wav2vec 2.0)</td>
<td>1,000,000시간</td>
</tr>
<tr>
<td><strong>Whisper (약지도 학습)</strong></td>
<td><strong>680,000시간</strong></td>
</tr>
</tbody></table>
<blockquote>
<p><strong>핵심 통찰:</strong><br>지도 학습과 비지도 학습 사이에 거대한 규모 격차가 있었습니다. Whisper는 이 격차를 <strong>약지도(Weakly Supervised) 학습</strong>으로 메웁니다. 정답이 100% 정확하지 않아도 됩니다. 양과 다양성으로 승부합니다.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>Whisper는 구조 자체는 평범한 인코더-디코더 트랜스포머입니다. 혁신은 구조가 아니라 <strong>데이터와 학습 방식</strong>에 있습니다.</p>
<h3 id="모델-아키텍처-table-1-기준">모델 아키텍처 (Table 1 기준)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>레이어</th>
<th>너비</th>
<th>헤드 수</th>
<th>파라미터</th>
</tr>
</thead>
<tbody><tr>
<td>Tiny</td>
<td>4</td>
<td>384</td>
<td>6</td>
<td>39M</td>
</tr>
<tr>
<td>Base</td>
<td>6</td>
<td>512</td>
<td>8</td>
<td>74M</td>
</tr>
<tr>
<td>Small</td>
<td>12</td>
<td>768</td>
<td>12</td>
<td>244M</td>
</tr>
<tr>
<td>Medium</td>
<td>24</td>
<td>1,024</td>
<td>16</td>
<td>769M</td>
</tr>
<tr>
<td><strong>Large</strong></td>
<td><strong>32</strong></td>
<td><strong>1,280</strong></td>
<td><strong>20</strong></td>
<td><strong>1,550M</strong></td>
</tr>
</tbody></table>
<h3 id="입력-처리-파이프라인">입력 처리 파이프라인</h3>
<ol>
<li>오디오를 <strong>16,000Hz</strong>로 리샘플링합니다.</li>
<li>25ms 윈도우, 10ms 스트라이드로 <strong>80채널 로그 멜 스펙트로그램</strong>을 계산합니다.</li>
<li>전처리 최솟값을 전체 데이터 기준 <strong>전역 정규화(-1~1)</strong>합니다.</li>
<li><strong>30초 단위</strong>로 잘라 인코더에 입력합니다.</li>
</ol>
<h3 id="핵심-혁신-멀티태스크-특수-토큰">핵심 혁신: 멀티태스크 특수 토큰</h3>
<p>Whisper는 하나의 모델로 여러 작업을 처리합니다. 어떤 작업을 할지를 <strong>특수 토큰</strong>으로 지정합니다.</p>
<pre><code>[이전 텍스트] → &lt;|startoftranscript|&gt; → &lt;언어 토큰&gt; → &lt;작업 토큰&gt; → &lt;타임스탬프 여부&gt; → 출력</code></pre><table>
<thead>
<tr>
<th>토큰</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td><code>&lt;|startoftranscript|&gt;</code></td>
<td>출력 시작 신호</td>
</tr>
<tr>
<td><code>&lt;언어 토큰&gt;</code></td>
<td>99개 언어 중 하나 지정</td>
</tr>
<tr>
<td><code>&lt;|transcribe|&gt;</code></td>
<td>같은 언어로 받아쓰기</td>
</tr>
<tr>
<td><code>&lt;|translate|&gt;</code></td>
<td>영어로 번역</td>
</tr>
<tr>
<td><code>&lt;|notimestamps|&gt;</code></td>
<td>타임스탬프 없이 출력</td>
</tr>
<tr>
<td><code>&lt;|nospeech|&gt;</code></td>
<td>음성 없음 (묵음 감지)</td>
</tr>
<tr>
<td><code>&lt;|endoftranscript|&gt;</code></td>
<td>출력 종료 신호</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>이것이 강력한 이유:</strong><br>음성 인식, 번역, 언어 감지, 음성 활동 감지(VAD)를 <strong>하나의 모델</strong>이 처리합니다. 별도의 파이프라인이 필요 없습니다. GPT-2와 동일한 바이트 수준 BPE 토크나이저를 사용해 텍스트 정규화 단계도 불필요합니다.</p>
</blockquote>
<h3 id="수식-이해하기">수식 이해하기</h3>
<p>$$P(Y | X) = \prod_{t=1}^{T} P(y_t | y_{&lt;t}, X, S)$$</p>
<p><strong>직관: 눈 가리고 릴레이 소설 쓰기</strong></p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$X$</td>
<td>입력된 30초짜리 오디오</td>
</tr>
<tr>
<td>$S$</td>
<td>특수 토큰 지시사항 (&quot;영어로 받아쓰기&quot; 등)</td>
</tr>
<tr>
<td>$y_{&lt;t}$</td>
<td>지금까지 출력한 단어들 전부</td>
</tr>
<tr>
<td>$y_t$</td>
<td>지금 뱉을 단 하나의 단어</td>
</tr>
<tr>
<td>$\prod$</td>
<td>각 단어 확률을 전부 곱함</td>
</tr>
</tbody></table>
<p>오디오($X$)라는 주제가 주어집니다. 지시사항($S$)을 받습니다. 앞사람들이 써놓은 문장($y_{&lt;t}$)을 읽습니다. 그 흐름에 가장 자연스러운 다음 단어($y_t$)를 고릅니다. 이 과정을 끝까지 반복하고 곱하면 전체 문장의 확률이 나옵니다.</p>
<h3 id="68만-시간-데이터-정제-파이프라인">68만 시간 데이터 정제 파이프라인</h3>
<p>방대한 인터넷 데이터에는 쓰레기가 많습니다. 저자들은 여러 단계의 필터링을 적용했습니다.</p>
<ol>
<li><strong>기계 생성 자막 제거</strong> — 기존 ASR 시스템이 만든 자막은 학습에 독이 됩니다. 전부 대문자/소문자만 있거나 쉼표가 없는 등 패턴으로 감지해 제거했습니다.</li>
<li><strong>언어 불일치 제거</strong> — 음성과 자막의 언어가 다른 쌍을 제거합니다. 단, 자막이 영어면 번역 학습 데이터로 재활용합니다.</li>
<li><strong>중복 제거</strong> — 퍼지 매칭으로 중복 텍스트를 제거합니다.</li>
<li><strong>초기 모델로 재검수</strong> — 첫 번째 모델을 훈련한 뒤 오류율이 높은 데이터 소스를 수동 검수해 저품질 소스를 추가 제거했습니다.</li>
</ol>
<hr>
<h3 id="📊-figure-1--whisper-전체-아키텍처-및-멀티태스크-학습-형식">📊 Figure 1 — Whisper 전체 아키텍처 및 멀티태스크 학습 형식</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/8a38dc0c-8c24-4637-801f-f8578eb7eca8/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 왼쪽은 680,000시간의 멀티태스크 학습 데이터 예시(영어 받아쓰기, 스페인어→영어 번역, 한국어 받아쓰기, 묵음 감지). 가운데는 인코더(로그멜 스펙트로그램 → 2-Conv + 트랜스포머 블록)와 디코더(크로스 어텐션 기반 트랜스포머 블록). 오른쪽은 특수 토큰 시퀀스가 각각 VAD, 언어 감지, 받아쓰기, 번역, 타임스탬프 예측으로 매핑되는 멀티태스크 출력 형식입니다.</li>
<li><strong>핵심 메시지:</strong> 4가지 다른 학습 데이터 유형(영어 받아쓰기, X→영어 번역, 비영어 받아쓰기, 묵음)을 하나의 통일된 토큰 시퀀스로 표현합니다. 전통적 파이프라인의 여러 모듈이 특수 토큰 하나로 대체됩니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>이 그림에 한국어 예시(&quot;언덕 위에 올라 내려다보면...&quot;)가 직접 등장합니다. 한국어를 포함한 다국어 학습이 얼마나 자연스럽게 하나의 토큰 형식으로 통합됐는지 보여줍니다. 특히 묵음을 <code>&lt;|nospeech|&gt;</code> 토큰 하나로 처리하는 것이 인상적입니다. 별도의 VAD 모듈이 필요 없어집니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--zero-shot-whisper-vs-지도-학습-모델의-강건성-비교">📊 Figure 2 — Zero-shot Whisper vs 지도 학습 모델의 강건성 비교</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/85914674-bef0-463f-b37f-8490ca6863cc/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> X축은 LibriSpeech dev-clean WER(기준 분포 성능), Y축은 Common Voice + CHiME-6 + TED-LIUM 평균 WER(분포 밖 성능). 점선은 이상적 강건성($y=x$). 파란 점들은 지도 학습 LibriSpeech 모델들, 빨간 점들은 Zero-shot Whisper 모델들, 별표는 사람(Alec) 성능입니다.</li>
<li><strong>핵심 메시지:</strong> LibriSpeech에서 비슷한 성능을 내는 지도 학습 모델(파란 점)과 Whisper(빨간 점)를 비교하면, 지도 학습 모델들은 Y축이 훨씬 위에 있습니다. 분포 밖에서 약 2배 더 많이 틀린다는 뜻입니다. 반면 Zero-shot Whisper는 사람의 95% 신뢰구간 안에 위치합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>&quot;기울기가 이상적 직선($y=x$)에 가까울수록 강건한 모델&quot;이라는 시각화 방식이 매우 직관적입니다. 지도 학습 모델들이 점선보다 훨씬 위에 몰려 있다는 것이 &quot;LibriSpeech 성능이 좋을수록 다른 곳에서 더 많이 틀린다&quot;는 역설적 패턴을 보여줍니다. Fine-tuning의 부작용을 이토록 명확하게 시각화한 그림입니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<h3 id="실험-설계의-핵심-원칙">실험 설계의 핵심 원칙</h3>
<p>저자들은 Whisper를 <strong>Zero-shot 환경</strong>에서만 평가했습니다. 즉, 평가 데이터셋의 훈련 데이터를 단 한 줄도 학습에 사용하지 않았습니다. 이것이 기존 SOTA 비교와 근본적으로 다른 점입니다.</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>평가 방식</strong></td>
<td>Zero-shot (어떤 평가셋도 Fine-tuning에 미사용)</td>
</tr>
<tr>
<td><strong>평가 데이터셋</strong></td>
<td>LibriSpeech + 12개 OOD 데이터셋</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>WER + 텍스트 정규화 후 WER</td>
</tr>
<tr>
<td><strong>비교 대상</strong></td>
<td>wav2vec 2.0 Large + 사람</td>
</tr>
</tbody></table>
<h3 id="영어-음성-인식-핵심-결과-table-2-기준">영어 음성 인식 핵심 결과 (Table 2 기준)</h3>
<table>
<thead>
<tr>
<th>데이터셋</th>
<th>wav2vec 2.0 Large</th>
<th>Whisper Large V2</th>
<th>상대 오류 감소</th>
</tr>
</thead>
<tbody><tr>
<td>LibriSpeech Clean</td>
<td>2.7%</td>
<td>2.7%</td>
<td>0.0%</td>
</tr>
<tr>
<td>CHiME-6 (잡음)</td>
<td>65.8%</td>
<td>25.5%</td>
<td><strong>61.2%</strong></td>
</tr>
<tr>
<td>Common Voice</td>
<td>29.9%</td>
<td>9.0%</td>
<td><strong>69.9%</strong></td>
</tr>
<tr>
<td>CORAAL (사투리)</td>
<td>35.6%</td>
<td>16.2%</td>
<td><strong>54.5%</strong></td>
</tr>
<tr>
<td>AMI IHM (회의)</td>
<td>37.0%</td>
<td>16.9%</td>
<td><strong>54.3%</strong></td>
</tr>
<tr>
<td><strong>평균 (14개 셋)</strong></td>
<td><strong>29.3%</strong></td>
<td><strong>12.8%</strong></td>
<td><strong>55.2%</strong> ✅</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>LibriSpeech에서는 두 모델이 동점(2.7%)입니다. 하지만 다른 환경으로 나가면 양상이 완전히 달라집니다. Whisper는 14개 데이터셋 평균에서 오류를 <strong>55.2%</strong> 줄였습니다. 특히 시끄러운 CHiME-6에서 65.8% → 25.5%로 떨어뜨린 것이 압도적입니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>Zero-shot 강건성</strong> — Fine-tuning 없이도 사람의 강건성과 비슷한 수준에 도달했습니다.</li>
<li><strong>멀티태스크 단일 모델</strong> — 음성 인식, 번역, 언어 감지, VAD를 토큰 하나로 전환합니다.</li>
<li><strong>스케일 다양성</strong> — Tiny(39M)부터 Large(1,550M)까지 5가지 모델로 엣지-클라우드 전방위 대응이 가능합니다.</li>
<li><strong>코드 및 모델 공개</strong> — 오픈소스로 공개해 후속 연구의 기반이 되었습니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>환각(Hallucination) 현상</strong> — 묵음 구간에서 모델이 앞뒤 문맥을 바탕으로 없는 말을 지어냅니다. 의료·법률 분야에서는 치명적입니다.</li>
<li><strong>실시간 처리 불가</strong> — 30초 단위로 처리하는 오프라인 구조입니다. 실시간 자막 서비스에 직접 쓸 수 없습니다. (→ MFLA 같은 후속 연구의 배경)</li>
<li><strong>영어 편향</strong> — 680,000시간 중 117,000시간만 비영어입니다. 비영어 언어 성능이 영어 대비 낮습니다.</li>
<li><strong>WER 평가의 한계</strong> — Zero-shot 모델은 데이터셋별 표기 형식(띄어쓰기, 대소문자 등)을 모릅니다. 실제로 맞았지만 형식 차이로 오답 처리됩니다. 저자들이 텍스트 정규화를 직접 개발해 보완했지만, 과적합 위험도 있습니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<ol>
<li><strong>스트리밍 적용</strong> — MFLA, Simul-Whisper 등 이미 등장한 연구들처럼 실시간 처리가 가능하도록 파인튜닝합니다.</li>
<li><strong>환각 억제</strong> — 음성 활동 감지를 강화하거나, <code>&lt;|nospeech|&gt;</code> 예측 신뢰도 임계값을 올려 묵음 구간 지어내기를 막습니다.</li>
<li><strong>저자원 언어 보완</strong> — 아프리카어, 남미 언어 등 데이터가 부족한 언어를 집중 보강하거나, 데이터가 많은 언어에서 지식을 전이합니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>&quot;LibriSpeech에서 사람보다 잘하는 모델이 왜 실전에서 더 나쁠까?&quot;라는 질문의 답을 이 논문에서 명확하게 얻었습니다. 사람과 기계는 같은 시험을 보지만 <strong>전혀 다른 능력을 측정받고 있습니다.</strong> 사람은 처음 보는 환경에서의 일반화 능력을, 기계는 해당 분포 안에서의 암기 능력을 평가받습니다. 벤치마크 성능이 실제 능력을 얼마나 왜곡할 수 있는지 뼈저리게 느꼈습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>&quot;좋은 AI 모델을 만들려면 데이터를 최대한 깨끗하게 정제해야 한다&quot;고 생각했습니다.</p>
<blockquote>
<p><strong>하지만 Whisper는 반대를 증명했습니다.</strong> 기계 생성 자막과 오류가 섞인 데이터를 엄청난 규모로 학습했고, 오히려 그 다양성 덕분에 어떤 환경에서도 무너지지 않는 강건함을 얻었습니다. &quot;데이터 정제&quot;가 답이 아니라 &quot;데이터 다양성과 규모&quot;가 강건성의 핵심이라는 관점이 바뀌었습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>온디바이스 다국어 음성 비서를 생각해보면, Tiny(39M) 모델이 단 하나로 음성 인식, 언어 감지, 번역을 모두 처리한다는 점이 매력적입니다. 스마트폰에서 네트워크 없이도 한국어→영어 동시 번역이 가능한 오프라인 앱의 핵심 엔진이 될 수 있을 것 같습니다. 다만 환각 현상을 억제하기 위해 신뢰도 기반 필터링 레이어를 추가하는 것이 실사용에서 중요할 것 같습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>Fine-tuning된 모델은 특정 데이터셋에 과적합되어 실제 환경에서 성능이 급락 — 벤치마크 성능이 실제 강건성을 반영하지 않음</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>약지도(Weakly Supervised) 방식으로 인터넷 오디오-자막 680,000시간 수집 + 멀티태스크 특수 토큰 + Zero-shot 학습</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>14개 OOD 데이터셋 평균 WER 55.2% 감소, 사람의 강건성 수준 달성, 음성 인식·번역·VAD·언어 감지 단일 모델 통합</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>&quot;같은 시험인데 사람과 기계가 서로 다른 능력을 측정받는다&quot;는 통찰 — LibriSpeech SOTA가 실제 강건성과 무관할 수 있음을 입증</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>묵음 구간 환각 현상, 오프라인 구조로 실시간 처리 불가, 비영어 언어 성능 불균형</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>MFLA/Simul-Whisper로 실시간화, 환각 억제, 저자원 언어 보완, SpeechLLM 결합</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>Whisper는 완벽한 데이터 대신 68만 시간의 지저분한 인터넷 데이터와 멀티태스크 약지도 학습으로, Fine-tuning 없이도 어떤 환경에서든 사람 수준의 강건함을 달성한 음성 인식의 패러다임 전환이다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Monotonic Finite Look-ahead Attention (MFLA)]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Monotonic-Finite-Look-ahead-Attention-MFLA</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Monotonic-Finite-Look-ahead-Attention-MFLA</guid>
            <pubDate>Thu, 12 Mar 2026 14:45:30 GMT</pubDate>
            <description><![CDATA[<h3 id="monotonic-finite-look-ahead-attention-mfla-httpsarxivorgpdf250603722">Monotonic Finite Look-ahead Attention (MFLA) (<a href="https://arxiv.org/pdf/2506.03722">https://arxiv.org/pdf/2506.03722</a>)</h3>
<h4 id="whisper를-실시간으로--과거는-무한히-미래는-딱-k개만-엿보는-스트리밍-음성-인식">Whisper를 실시간으로 — 과거는 무한히, 미래는 딱 k개만 엿보는 스트리밍 음성 인식</h4>
<blockquote>
<p>훈련과 실전의 괴리를 CIF + MFLA + Wait-k 세 가지 조합으로 해결하여,<br><strong>Whisper를 그대로 파인튜닝해 실시간 스트리밍 음성 인식 시스템으로 변환한 prefix-to-prefix 프레임워크.</strong><br>arXiv 2025 | Yinfeng Xia, Huiyan Li et al. (Honor Device Co., Ltd. / Shanghai Jiao Tong University)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 아주 실용적인 질문에서 출발합니다.</p>
<p><strong>&quot;Whisper는 이미 뛰어난 음성 인식 모델인데, 왜 실시간 자막에 바로 쓸 수 없을까?&quot;</strong></p>
<p>Whisper는 대규모 약지도(Weakly Supervised) 사전학습으로 다국어 음성 인식에서 강력한 성능을 보여주는 모델입니다. 하지만 구조 자체가 발화가 끝날 때까지 기다려야 하는 오프라인 Seq2Seq 모델입니다. 실시간 자막이나 동시통역처럼 즉각적인 응답이 필요한 서비스에는 쓸 수 없습니다.</p>
<p>이 논문은 Whisper를 처음부터 다시 학습시키지 않고 <strong>LoRA 파인튜닝만으로</strong> 실시간 스트리밍 모델로 변환하는 방법을 제안합니다. 핵심은 세 가지 모듈의 조합입니다. CIF(연속 누적 발화 타이밍 감지), MFLA(무한 왼쪽 문맥 + 유한 오른쪽 문맥 어텐션), Wait-k 디코딩이 함께 작동하면서 실시간성과 정확도를 동시에 달성합니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이런 연구가 필요한지 배경을 살펴봅니다.</p>
<h3 id="whisper의-강점과-치명적-한계">Whisper의 강점과 치명적 한계</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>강점</strong></td>
<td>68만 시간 약지도 학습, 다국어 지원, 높은 정확도</td>
</tr>
<tr>
<td><strong>한계</strong></td>
<td>발화 전체가 입력돼야 처리 시작 — 본질적으로 오프라인 모델</td>
</tr>
<tr>
<td><strong>기존 시도</strong></td>
<td>Knowledge Distillation, Speculative Decoding → 속도 개선이지만 오프라인 구조 유지</td>
</tr>
</tbody></table>
<h3 id="스트리밍-음성-인식의-기존-접근법과-한계">스트리밍 음성 인식의 기존 접근법과 한계</h3>
<table>
<thead>
<tr>
<th>방법</th>
<th>아이디어</th>
<th>한계</th>
</tr>
</thead>
<tbody><tr>
<td><strong>개선된 Wait-k 정책</strong></td>
<td>k개 청크가 들어올 때까지 기다린 후 고정 속도로 출력</td>
<td>말하기 속도 변화에 취약, 묵음 구간 처리 불안정</td>
</tr>
<tr>
<td><strong>Local Agreement</strong></td>
<td>연속된 두 청크의 최장 공통 접두사만 출력</td>
<td>높은 고정 지연 시간</td>
</tr>
<tr>
<td><strong>Simul-Whisper</strong></td>
<td>디코딩을 적절한 시점에 멈추고 불안정 구간 버림</td>
<td>복잡한 온라인 디코딩 파이프라인</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>공통 문제:</strong> 기존 방법들은 단편적(One-dimensional)입니다. 지연 시간과 품질 사이의 균형을 유연하게 조절하지 못합니다.</p>
</blockquote>
<h3 id="이-논문이-달라지는-지점">이 논문이 달라지는 지점</h3>
<p>기존 Seq2Seq 패러다임(전체 입력 → 전체 출력)을 <strong>prefix-to-prefix 패러다임</strong>으로 바꿉니다.</p>
<blockquote>
<p>prefix-to-prefix: 입력 접두사가 들어오면 그에 대응하는 출력 접두사를 즉시 냅니다. 훈련과 추론 조건이 일치하므로 성능 저하가 없습니다.</p>
</blockquote>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;훈련과 실전의 불일치(Asynchronous Processing Problem)&quot;</strong> 입니다.</p>
<h3 id="훈련-추론-불일치">훈련-추론 불일치</h3>
<table>
<thead>
<tr>
<th>단계</th>
<th>조건</th>
<th>결과</th>
</tr>
</thead>
<tbody><tr>
<td><strong>훈련 시</strong></td>
<td>전체 발화 소스를 다 보고 학습</td>
<td>완벽한 문맥 파악</td>
</tr>
<tr>
<td><strong>실전 추론 시</strong></td>
<td>현재까지 들어온 부분 소스만 사용</td>
<td>문맥 부족 → 성능 하락</td>
</tr>
</tbody></table>
<p>이 불일치는 단순히 모델을 빠르게 만드는 것으로 해결되지 않습니다. <strong>훈련 방식 자체를 실전처럼</strong> 바꿔야 합니다.</p>
<h3 id="경계-불안정성-문제">경계 불안정성 문제</h3>
<p>고정 길이 청크로 오디오를 자르면 단어 경계가 청크 끝에 걸릴 수 있습니다. 예를 들어 &quot;school&quot;의 절반만 들어온 상태에서 글자를 출력해야 한다면 신뢰할 수 없는 결과가 나옵니다.</p>
<h3 id="직관적-비유-🧩">직관적 비유 🧩</h3>
<p>퍼즐 조각이 1초에 하나씩 배달된다고 상상해 봅시다.</p>
<ul>
<li><strong>기존 방식:</strong> 모든 조각이 다 도착할 때까지 기다렸다가 퍼즐을 완성하고 &quot;코끼리!&quot;라고 외칩니다.</li>
<li><strong>MFLA 방식:</strong> 코끼리 코 모양이 얼추 완성됐을 때 멈추되, 방금 막 배달된 다음 조각 k개만 살짝 훔쳐보고 바로 &quot;코끼리!&quot;라고 외칩니다.</li>
</ul>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>Streaming-Whisper는 <strong>인코더(MoChA) + 예측기(CIF) + 디코더(MFLA)</strong> 세 모듈이 유기적으로 작동합니다.</p>
<h3 id="전체-구조-개요">전체 구조 개요</h3>
<p>$$H = f(X) \quad \text{(인코더: 음성 → 은닉 상태)}$$
$$\alpha_j = e(h_j) \quad \text{(예측기: 토큰 경계 가중치)}$$
$$y_i = g(y_{i-1}, h_{1:T}) \quad \text{(디코더: 은닉 상태 → 문자)}$$</p>
<h3 id="모듈-1-인코더--mocha로-청크-단위-처리">모듈 1: 인코더 — MoChA로 청크 단위 처리</h3>
<p>Whisper 인코더의 기존 합성곱 레이어를 <strong>인과 합성곱(Causal Convolution)</strong> 으로 교체합니다. 미래 청크를 볼 수 없게 막습니다. 인코더 어텐션에는 <strong>MoChA</strong>를 적용해 현재 청크와 이전 청크들만 참조하도록 제한합니다.</p>
<table>
<thead>
<tr>
<th>설정</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td>청크 크기 $w$</td>
<td>훈련 시 균등 분포 $[32, 128]$에서 샘플링</td>
</tr>
<tr>
<td>$w = \infty$</td>
<td>오프라인(전체 어텐션)과 동일 — 오프라인을 온라인의 특수 케이스로 통일</td>
</tr>
</tbody></table>
<h3 id="모듈-2-예측기predictor--cif로-토큰-경계-감지">모듈 2: 예측기(Predictor) — CIF로 토큰 경계 감지</h3>
<p>CIF(Continuous Integrate-and-Fire)는 음성 프레임의 누적 가중치가 1을 넘는 순간 토큰 하나를 발화하는 메커니즘입니다.</p>
<p><strong>직관: 물통 채우기 비유</strong></p>
<p>빗방울(음성 프레임)이 조금씩 물통에 떨어집니다. 물통이 가득 차서 <strong>1리터 눈금을 넘는 순간</strong> 밸브가 열리며 물 한 컵(토큰 하나)이 출력됩니다.</p>
<p>$$\sum_{i=1}^{t} \alpha_i \geq 1 \quad \Rightarrow \quad \text{토큰 하나 출력}$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$\alpha_j$</td>
<td>프레임 $j$의 토큰 가중치 (예측기 출력)</td>
</tr>
<tr>
<td>$\sum \alpha_i \geq 1$</td>
<td>토큰 하나가 완성됐다는 신호</td>
</tr>
</tbody></table>
<p>CIF는 세 가지 역할을 동시에 수행합니다. 훈련 시 MFLA의 오른쪽 문맥 윈도우를 가이드합니다. 추론 시 디코딩을 멈춰야 할 시점을 추적합니다. 반복 출력(Repetition) 문제를 방지합니다.</p>
<h3 id="모듈-3-디코더--mfla로-무한-왼쪽--유한-오른쪽">모듈 3: 디코더 — MFLA로 무한 왼쪽 + 유한 오른쪽</h3>
<p>MFLA의 핵심 아이디어는 단순합니다.</p>
<blockquote>
<p><strong>왼쪽(과거):</strong> 제한 없이 전부 참조합니다.<br><strong>오른쪽(미래):</strong> 딱 $k$개 프레임까지만 참조합니다.</p>
</blockquote>
<p>$$C_t = \text{Attention}(Q_t,\ K_{\leq t+k},\ V_{\leq t+k})$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$Q_t$</td>
<td>현재 시각 $t$의 쿼리</td>
</tr>
<tr>
<td>$K_{\leq t+k}$</td>
<td>과거 전체 + 미래 $k$개까지의 키</td>
</tr>
<tr>
<td>$V_{\leq t+k}$</td>
<td>과거 전체 + 미래 $k$개까지의 값</td>
</tr>
</tbody></table>
<p><strong>직관: 밤길 헤드라이트 비유</strong></p>
<p>백미러(과거)는 지나온 길 전체를 볼 수 있습니다. 하지만 앞길(미래)은 헤드라이트가 비추는 딱 $k$미터 앞까지만 보입니다. 헤드라이트의 가시거리 $k$를 조절해 안전(정확도)과 속도(지연) 사이의 균형을 맞춥니다.</p>
<table>
<thead>
<tr>
<th>$k$ 값</th>
<th>지연 시간</th>
<th>정확도</th>
</tr>
</thead>
<tbody><tr>
<td>$k=1$</td>
<td>매우 짧음</td>
<td>다소 낮음</td>
</tr>
<tr>
<td>$k=3$</td>
<td>중간</td>
<td>높음</td>
</tr>
<tr>
<td>$k=\infty$</td>
<td>오프라인</td>
<td>최고 (오프라인과 동일)</td>
</tr>
</tbody></table>
<h3 id="wait-k-디코딩-전략">Wait-k 디코딩 전략</h3>
<p>훈련 시 MFLA로 $k$개 미래 프레임을 보도록 학습했으므로, 추론 시에도 CIF 누적값이 $k$를 초과할 때마다 토큰을 하나씩 출력하면 훈련-추론 조건이 일치합니다.</p>
<pre><code>누적 가중치 α에 현재 프레임 가중치를 더함
α가 k를 초과하는 동안:
    토큰 하나 출력
    α에서 1 차감
다음 프레임으로 이동</code></pre><h3 id="2단계-파인튜닝-전략">2단계 파인튜닝 전략</h3>
<p>MFLA 생성이 예측기(CIF)에 의존하므로, 순서대로 학습시켜야 합니다.</p>
<table>
<thead>
<tr>
<th>단계</th>
<th>방식</th>
<th>목적</th>
</tr>
</thead>
<tbody><tr>
<td><strong>1단계</strong></td>
<td>디코더에 Full Attention으로만 훈련</td>
<td>기본 언어 모델링 능력 확보</td>
</tr>
<tr>
<td><strong>2단계</strong></td>
<td>Full Attention + Monotonic Attention 혼합</td>
<td>실시간 조건 적응</td>
</tr>
</tbody></table>
<hr>
<h3 id="📊-figure-1--streaming-whisper-전체-구조">📊 Figure 1 — Streaming-Whisper 전체 구조</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/5df0ead3-29ca-4c00-9c73-8d1d398d58ab/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 입력 음성 $x_1, \ldots, x_T$가 인코더(Encoder + LoRA)를 거쳐 은닉 상태 $h_1, \ldots, h_T$가 되고, 예측기(Predictor)가 토큰 가중치 $\alpha_1, \ldots, \alpha_T$를 출력합니다. 디코더(Decoder + LoRA)는 $\alpha$에 가이드된 MFLA로 출력 토큰 $y_1, \ldots, y_N$을 생성합니다. 손실 함수는 예측기의 MRE Loss와 디코더의 CE Loss 두 가지를 동시에 최적화합니다.</li>
<li><strong>핵심 메시지:</strong> Whisper 원래 구조에 예측기 하나만 추가하고, 나머지는 LoRA로 파인튜닝합니다. 구조 변경을 최소화하면서 스트리밍을 가능하게 만든 효율적인 설계입니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>LoRA로 인코더와 디코더 파라미터를 동결하고 소수의 저랭크 행렬만 학습하므로, Whisper가 사전학습으로 쌓은 음성 지식을 그대로 보존하면서 스트리밍 능력만 추가로 주입합니다. 처음부터 학습하는 것과 달리 훈련 비용이 극적으로 줄어듭니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--mocha인코더와-mfla디코더-어텐션-패턴-비교">📊 Figure 2 — MoChA(인코더)와 MFLA(디코더) 어텐션 패턴 비교</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/d162b6d2-f1e6-49e5-b570-9a04982f3e8e/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> (a)(b)는 인코더의 MoChA — 청크 크기 1과 2의 어텐션 마스크 패턴. (c)는 청크 크기 ∞인 오프라인 풀 어텐션. (d)(e)는 디코더의 MFLA — Look-ahead span 1과 2의 패턴. (f)는 Look-ahead ∞인 오프라인과 동일한 패턴.</li>
<li><strong>핵심 메시지:</strong> 청크 크기/$w$와 Look-ahead span/$k$ 모두 $\infty$로 설정하면 오프라인 풀 어텐션과 완전히 동일합니다. 즉 <strong>오프라인이 온라인의 특수 케이스</strong>로 통일됩니다. 하나의 모델로 오프라인과 온라인 디코딩을 모두 지원합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>인코더(MoChA)와 디코더(MFLA)가 서로 다른 방향의 어텐션 제약을 담당합니다. 인코더는 청크 단위로 왼→오를 제한하고, 디코더는 무한 왼쪽 + 유한 오른쪽 $k$개를 허용합니다. 두 모듈이 역할 분담해 전체 시스템의 인과성을 보장합니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 4가지 모델 크기 × 4개 언어 × 다수 데이터셋에서 체계적으로 검증했습니다.</p>
<h3 id="실험-설정">실험 설정</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>WenetSpeech4TTS(중국어), LibriSpeech(영어), MLS(독·스페인어), VoxPopuli(독·스페인·영어)</td>
</tr>
<tr>
<td><strong>모델 아키텍처</strong></td>
<td>Whisper Small / Medium / Large-V3 / <strong>Large-V3-Turbo</strong></td>
</tr>
<tr>
<td><strong>지연 지표</strong></td>
<td>DAL (Differentiable Average Lagging) — 이상적 스트리밍 대비 평균 지연</td>
</tr>
<tr>
<td><strong>비교 기준</strong></td>
<td>Local Agreement 정책 (Baseline)</td>
</tr>
<tr>
<td><strong>청크 길이</strong></td>
<td>온라인 디코딩 시 1초</td>
</tr>
</tbody></table>
<h3 id="아키텍처별-오프라인온라인-wer-table-1-요약">아키텍처별 오프라인/온라인 WER (Table 1 요약)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>오프라인 평균 WER</th>
<th>온라인 평균 WER</th>
<th>성능 저하</th>
</tr>
</thead>
<tbody><tr>
<td>Small</td>
<td>7.66%</td>
<td>9.38%</td>
<td>+1.72%p</td>
</tr>
<tr>
<td>Medium</td>
<td>6.06%</td>
<td>7.62%</td>
<td>+1.56%p</td>
</tr>
<tr>
<td>Large-V3</td>
<td>5.53%</td>
<td>6.71%</td>
<td>+1.18%p</td>
</tr>
<tr>
<td><strong>Large-V3-Turbo</strong></td>
<td><strong>5.63%</strong></td>
<td><strong>7.17%</strong></td>
<td><strong>+1.54%p</strong></td>
</tr>
</tbody></table>
<blockquote>
<p>모델이 클수록 오프라인-온라인 성능 격차가 작아집니다. Large-V3가 1.18%p로 가장 적은 저하를 보였습니다.</p>
</blockquote>
<h3 id="핵심-절제-실험-table-2-large-v3-turbo-기준">핵심 절제 실험 (Table 2: Large-V3-Turbo 기준)</h3>
<table>
<thead>
<tr>
<th>방법</th>
<th>WER (↓)</th>
<th>DAL (↓)</th>
<th>FLOPs (↓)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Local Agreement (Baseline)</strong></td>
<td>7.06%</td>
<td>1.65s</td>
<td>37.56G</td>
</tr>
<tr>
<td>Wait-1</td>
<td>7.59%</td>
<td>0.93s</td>
<td>34.35G</td>
</tr>
<tr>
<td>Wait-2</td>
<td>7.25%</td>
<td>1.17s</td>
<td>33.48G</td>
</tr>
<tr>
<td><strong>Wait-3</strong></td>
<td><strong>7.17%</strong></td>
<td><strong>1.41s</strong></td>
<td><strong>32.63G</strong></td>
</tr>
<tr>
<td>Wait-3† (버퍼 상태 재사용)</td>
<td>7.31%</td>
<td>1.41s</td>
<td><strong>12.77G</strong> ✅</td>
</tr>
<tr>
<td>Wait-5</td>
<td>7.10%</td>
<td>1.87s</td>
<td>31.06G</td>
</tr>
<tr>
<td>Wait-∞ (오프라인)</td>
<td>6.81%</td>
<td>6.71s</td>
<td>12.85G</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>Wait-3은 Local Agreement 대비 WER이 0.11%p만 나빠지면서 <strong>지연 시간을 14.54% 단축</strong>합니다. Wait-3†(버퍼 상태 재사용)는 WER이 0.14%p 더 낮아지는 대신 <strong>디코더 연산량을 60.86% 절감</strong>합니다. Wait-k를 쓸수록 Local Agreement 대비 WER은 근소하게 낮아지지만 지연은 훨씬 짧습니다.</p>
</blockquote>
<h3 id="speechllm-확장-table-3">SpeechLLM 확장 (Table 3)</h3>
<p>Whisper-Large-V3 + Qwen2.5-3B-Instruct를 결합한 SpeechLLM에도 MFLA를 적용했습니다. 오프라인 평균 WER 3.14%, 온라인 4.12%로, Whisper 단독보다 전 항목에서 우수한 성능을 보였습니다.</p>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>Whisper 재활용</strong> — 처음부터 학습하지 않고 LoRA 파인튜닝만으로 스트리밍 변환. 훈련 비용이 극적으로 낮습니다.</li>
<li><strong>훈련-추론 일치</strong> — prefix-to-prefix 패러다임이 훈련-추론 불일치를 근본적으로 해결합니다.</li>
<li><strong>$k$ 하나로 지연-품질 트레이드오프 제어</strong> — Wait-k의 $k$ 값을 바꾸는 것만으로 지연과 정확도를 유연하게 조절합니다.</li>
<li><strong>오프라인-온라인 통일</strong> — $k=\infty$로 설정하면 오프라인과 동일. 하나의 모델로 두 가지 운영 모드를 지원합니다.</li>
<li><strong>SpeechLLM 확장 가능</strong> — LLM과 결합해도 동일한 프레임워크가 작동함을 실험으로 입증했습니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>예측기 구조 단순</strong> — 예측기가 두 개의 선형 레이어와 ReLU로만 구성되어 프레임 수준 토큰 가중치 추정에 편향이 발생합니다. 저자가 직접 인정한 한계입니다.</li>
<li><strong>LoRA의 인코더 개선 효과 제한</strong> — Wait-∞(오프라인 한계)와 오프라인 디코딩의 1.18%p 격차는 LoRA 파인튜닝이 스트리밍 음성 처리를 위한 인코더 개선에 충분하지 않음을 보여줍니다.</li>
<li><strong>고정된 청크 길이</strong> — 온라인 디코딩은 1초 고정 청크를 씁니다. 말하기 속도 변화에 유연하게 대응하지 못합니다.</li>
<li><strong>영어/유럽어 외 검증 부족</strong> — 중국어는 포함되었지만 그 외 아시아 언어에서의 성능은 검증되지 않았습니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<ol>
<li><strong>동적 $k$ 조절 (Dynamic MFLA)</strong> — 쉬운 단어는 짧은 $k$로 빠르게, 발음이 애매한 전문 용어는 더 긴 $k$로 신중하게 처리합니다.</li>
<li><strong>예측기 고도화</strong> — 단순 선형 레이어 대신 트랜스포머 기반 예측기를 써서 프레임-토큰 경계 추정 정확도를 높입니다.</li>
<li><strong>풀 파인튜닝 구간 추가</strong> — 인코더 일부 레이어는 LoRA 외에 풀 파인튜닝을 허용해 스트리밍 음성에 대한 인코더 적응력을 높입니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>&quot;실시간 모델을 만들려면 처음부터 실시간용으로 설계해야 한다&quot;고 생각했습니다. 하지만 MFLA는 <strong>기존의 강력한 오프라인 모델(Whisper)에 제약을 추가하는 방식</strong>으로 실시간화를 달성했습니다. 새로운 모델을 만드는 것보다 기존 모델의 시야를 줄이는 것이 더 효율적인 전략이 될 수 있다는 것을 배웠습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>미래 정보를 전혀 보지 않아야만 &quot;진짜 실시간&quot;이라고 생각했습니다.</p>
<blockquote>
<p>하지만 MFLA는 <strong>딱 $k$개만큼의 미래</strong>를 허용하는 것이 핵심입니다. Wait-3(약 3토큰 지연)만으로 오프라인과 1.18%p 차이까지 따라잡았습니다. &quot;미래를 얼마나 볼 것인가&quot;가 이진 선택이 아닌 <strong>연속적 설계 파라미터</strong>라는 관점이 실용적으로 중요하다는 것을 깨달았습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>온디바이스 실시간 회의록 생성 시나리오에서 MFLA가 실용적인 선택지가 될 것 같습니다. 특히 Wait-3†(버퍼 상태 재사용)가 동일 지연에서 FLOPs를 60.86% 줄인다는 결과는, 배터리와 메모리가 제한된 스마트폰 환경에서도 충분히 작동할 가능성을 시사합니다. LLM과의 결합 가능성도 확인됐으므로, 온디바이스 SpeechLLM 형태로 발전시켜보는 방향이 흥미로울 것 같습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>Whisper는 성능이 뛰어나지만 오프라인 구조 — 훈련-추론 불일치로 실시간 적용 불가</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>CIF(토큰 경계 감지) + MFLA(무한 왼쪽 + 유한 오른쪽 $k$) + Wait-k 디코딩 = prefix-to-prefix 파인튜닝</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>Wait-3 기준 Local Agreement 대비 WER +0.11%p에 지연 14.54% 단축, Wait-3†로 FLOPs 60.86% 절감</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>$k=\infty$로 설정하면 오프라인과 완전히 동일 — 오프라인을 온라인의 특수 케이스로 통일하는 우아한 설계</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>예측기 구조 단순, LoRA의 인코더 개선 한계, 오프라인-온라인 간 여전히 1.18%p 이상의 격차</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>Dynamic $k$ 적응, 예측기 트랜스포머화, 온디바이스 SpeechLLM과의 결합</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>MFLA는 Whisper를 처음부터 다시 만들지 않고, CIF로 토큰 경계를 감지하고 무한 왼쪽 + 유한 오른쪽 $k$개만 보는 어텐션으로 훈련-추론 불일치를 해결해, 단 하나의 파인튜닝으로 강력한 오프라인 모델을 실시간 스트리밍 시스템으로 변환한 실용적 프레임워크다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Monotonic Chunkwise Attention (MoChA)]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Monotonic-Chunkwise-Attention-MoChA</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Monotonic-Chunkwise-Attention-MoChA</guid>
            <pubDate>Tue, 10 Mar 2026 12:52:55 GMT</pubDate>
            <description><![CDATA[<h3 id="monotonic-chunkwise-attention-mocha-httpsarxivorgpdf171205382">Monotonic Chunkwise Attention (MoChA) (<a href="https://arxiv.org/pdf/1712.05382">https://arxiv.org/pdf/1712.05382</a>)</h3>
<h4 id="실시간으로-달리면서-방금-지나온-길을-되돌아보는-어텐션-메커니즘">실시간으로 달리면서 방금 지나온 길을 되돌아보는 어텐션 메커니즘</h4>
<blockquote>
<p>미래를 컨닝하지 않고 왼쪽에서 오른쪽으로만 진행하면서,<br><strong>멈춘 순간 바로 직전 2~8개를 묶어 소프트 어텐션으로 훑어보는</strong> 실시간 어텐션의 혁신.<br>ICLR 2018 | Chung-Cheng Chiu, Colin Raffel (Google Brain)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 어텐션 메커니즘이 가진 오랜 딜레마를 정면으로 파고듭니다.</p>
<p><strong>&quot;정확하려면 전체를 봐야 하고, 실시간이려면 하나만 봐야 한다.&quot;</strong></p>
<p>기존의 소프트 어텐션은 입력 전체를 다 읽어야만 결과를 냅니다. 동시통역이나 실시간 자막처럼 즉각 반응해야 하는 서비스에 쓸 수 없습니다. 반면 실시간 처리를 위해 만들어진 단방향 어텐션(Hard Monotonic Attention)은 딱 하나의 프레임만 보기 때문에 앞뒤 문맥을 놓쳐 정확도가 크게 떨어졌습니다.</p>
<p>이 논문은 <strong>단방향으로 진행하되, 멈춘 순간 직전 2~8개를 한 묶음으로 묶어 소프트 어텐션을 추가로 수행</strong>하는 MoChA(Monotonic Chunkwise Attention)를 제안합니다. 이 글을 끝까지 읽으시면, 왜 &#39;방금 지나온 짧은 구간&#39;을 되돌아보는 것만으로도 전체를 다 읽는 효과를 낼 수 있는지 직관적으로 이해하게 되실 겁니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 어텐션 메커니즘의 진화 흐름을 먼저 살펴봅니다.</p>
<h3 id="어텐션-메커니즘의-3가지-세대">어텐션 메커니즘의 3가지 세대</h3>
<table>
<thead>
<tr>
<th>방식</th>
<th>설명</th>
<th>장점</th>
<th>치명적 한계</th>
</tr>
</thead>
<tbody><tr>
<td><strong>소프트 어텐션</strong></td>
<td>매 출력 시각마다 입력 전체를 참조</td>
<td>정확도 최고</td>
<td>$O(TU)$ 이차 복잡도, 실시간 불가</td>
</tr>
<tr>
<td><strong>하드 단조 어텐션</strong></td>
<td>왼→오 스캔, 한 지점에서 멈춰 딱 하나만 참조</td>
<td>실시간 + 선형 복잡도</td>
<td>단 하나의 프레임만 참조 → 정확도 하락</td>
</tr>
<tr>
<td><strong>MoChA (이 논문)</strong></td>
<td>왼→오 스캔, 멈춘 지점 기준으로 직전 W개를 소프트 어텐션</td>
<td>실시간 + 문맥 파악</td>
<td>묶음 크기 W가 고정됨</td>
</tr>
</tbody></table>
<h3 id="소프트-어텐션의-이차-비용-문제">소프트 어텐션의 이차 비용 문제</h3>
<p>소프트 어텐션의 비용은 입력 길이 $T$와 출력 길이 $U$의 곱인 $O(TU)$입니다.</p>
<blockquote>
<p>입력 1,000프레임, 출력 100글자인 경우: <strong>10만 번의 계산</strong>이 필요합니다. 입력이 2배 길어지면 계산량은 4배가 됩니다. 매우 긴 문서 요약 같은 작업에서는 컴퓨터가 뻗어버릴 수 있습니다.</p>
</blockquote>
<p>반면 하드 단조 어텐션은 $O(\max(T, U))$ 선형 복잡도로 이 문제를 해결했습니다. 하지만 딱 하나의 프레임만 보는 제약이 정확도를 크게 낮췄습니다. (WSJ 음성 인식 기준 WER 17.4% vs 소프트 어텐션 14.2%)</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 하나입니다.</p>
<blockquote>
<p><strong>&quot;하드 단조 어텐션은 실시간성은 얻었지만, 단일 프레임 참조와 엄격한 단조 정렬이라는 두 가지 제약이 소프트 어텐션과의 성능 격차를 만든다.&quot;</strong></p>
</blockquote>
<h3 id="두-가지-제약의-한계">두 가지 제약의 한계</h3>
<table>
<thead>
<tr>
<th>제약</th>
<th>문제</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>단일 프레임 참조</strong></td>
<td>한 소리 프레임만으로는 발음의 의미를 알 수 없음</td>
<td>&quot;학&quot;이라는 소리 하나만 듣고 &quot;학교&quot;인지 &quot;학생&quot;인지 맞혀야 함</td>
</tr>
<tr>
<td><strong>엄격한 단조 정렬</strong></td>
<td>어순이 뒤바뀌는 번역 등 비단조 태스크에서 성능 폭락</td>
<td>문서 요약에서 Hard Monotonic은 ROUGE-1이 8점 가까이 하락</td>
</tr>
</tbody></table>
<h3 id="직관적-비유-🏀">직관적 비유 🏀</h3>
<p>농구 중계 해설자를 생각해 봅시다.</p>
<ul>
<li><strong>소프트 어텐션:</strong> 경기 전체 영상을 다 돌려본 뒤 해설합니다. 정확하지만 실시간이 아닙니다.</li>
<li><strong>하드 단조 어텐션:</strong> 경기를 보다가 &quot;지금 이 장면!&quot;에서 딱 멈추고 그 순간 사진 한 장만 보고 해설합니다. 빠르지만 맥락이 없습니다.</li>
<li><strong>MoChA:</strong> &quot;지금 이 장면!&quot;에서 멈추되, 방금 전 2~3초의 짧은 리플레이를 같이 보고 해설합니다. 빠르면서도 맥락이 살아 있습니다.</li>
</ul>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>MoChA는 두 개의 독립적인 어텐션 함수를 결합합니다.</p>
<h3 id="전체-작동-흐름-테스트-시">전체 작동 흐름 (테스트 시)</h3>
<p>$$v = t_i - w + 1$$
$$u_{i,k} = ChunkEnergy(s_{i-1}, h_k), \quad k \in {v, v+1, \ldots, t_i}$$
$$c_i = \sum_{k=v}^{t_i} \frac{\exp(u_{i,k})}{\sum_{l=v}^{t_i} \exp(u_{i,l})} h_k$$</p>
<ol>
<li><strong>탐색 및 정지</strong> — MonotonicEnergy로 왼→오 스캔하다 $p_{i,j} \geq 0.5$인 지점 $t_i$에서 멈춥니다.</li>
<li><strong>묶음 경계 설정</strong> — 멈춘 위치 $t_i$ 기준으로 직전 $w$개를 하나의 청크로 묶습니다.</li>
<li><strong>청크 내 소프트 어텐션</strong> — ChunkEnergy로 청크 내 각 프레임의 중요도를 계산합니다.</li>
<li><strong>문맥 벡터 생성</strong> — 중요도 가중 평균으로 컨텍스트 벡터 $c_i$를 만들어 디코더에 넘깁니다.</li>
</ol>
<h3 id="두-가지-독립된-에너지-함수">두 가지 독립된 에너지 함수</h3>
<table>
<thead>
<tr>
<th>함수</th>
<th>역할</th>
<th>결과</th>
</tr>
</thead>
<tbody><tr>
<td><strong>MonotonicEnergy</strong></td>
<td>여기서 멈출지 결정</td>
<td>$p_{i,j}$ : 멈출 확률 (0~1)</td>
</tr>
<tr>
<td><strong>ChunkEnergy</strong></td>
<td>청크 안에서 어디가 중요한지 판단</td>
<td>$u_{i,k}$ : 소프트 어텐션 에너지</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>파라미터 증가가 고작 1%!</strong><br>ChunkEnergy 함수를 추가하는 것이 전체 모델 파라미터를 약 1%만 늘립니다. 아주 작은 비용으로 큰 성능 향상을 얻은 것입니다.</p>
</blockquote>
<h3 id="w1이면-하드-단조-어텐션과-동일">w=1이면 하드 단조 어텐션과 동일</h3>
<p>$w=1$로 설정하면 직전 프레임 하나만 묶어보므로 MoChA가 하드 단조 어텐션으로 환원됩니다. MoChA는 하드 단조 어텐션의 완전한 일반화(Generalization)입니다.</p>
<h3 id="직관적-예시-4가지-💡">직관적 예시 4가지 💡</h3>
<table>
<thead>
<tr>
<th>비유</th>
<th>상황</th>
<th>MoChA의 동작</th>
</tr>
</thead>
<tbody><tr>
<td><strong>스마트폰 자동완성</strong></td>
<td>&#39;안녕ㅎ&#39;까지 쳤을 때</td>
<td>멈추는 순간 &#39;안&#39;, &#39;녕&#39;, &#39;ㅎ&#39; 3글자를 묶어 &quot;안녕하세요&quot; 추천</td>
</tr>
<tr>
<td><strong>스포츠 비디오 판독</strong></td>
<td>반칙 의심 순간에 영상 정지</td>
<td>정지 화면 직전 2~3초 리플레이를 묶어서 함께 검토</td>
</tr>
<tr>
<td><strong>회전 초밥집</strong></td>
<td>원하는 초밥이 지나갈 때</td>
<td>그 접시 하나만 집는 게 아니라 바로 앞 2~3개 접시를 세트로 집음</td>
</tr>
<tr>
<td><strong>손전등 탐독</strong></td>
<td>중요한 단어에서 멈춤</td>
<td>멈춘 순간 손전등 불빛을 살짝 넓혀 방금 읽은 앞 단어들도 같이 비춤</td>
</tr>
</tbody></table>
<hr>
<h3 id="수식-이해하기">수식 이해하기</h3>
<h4 id="핵심-수식-데이터-j의-최종-관심도-beta_ij">핵심 수식: 데이터 $j$의 최종 관심도 $\beta_{i,j}$</h4>
<p><strong>직관적 설명 먼저 — 오디션 합격 확률 비유:</strong><br>오디션 참가자 $j$가 최종 합격할 확률은 두 가지가 동시에 일어나야 합니다. 심사위원이 $j$ 근처 위치 $k$에서 탐색을 멈춰야 하고($\alpha_{i,k}$), 그 묶음 안에서 $j$가 다른 참가자보다 눈에 띄어야 합니다($\exp(u_{i,j}) / \sum \exp$). 이 두 확률을 곱하고, 멈출 수 있는 모든 위치 $k$에 대해 더합니다.</p>
<p>$$\beta_{i,j} = \sum_{k=j}^{j+W-1} \left( \alpha_{i,k} \cdot \frac{\exp(u_{i,j})}{\sum_{l=k-W+1}^{k} \exp(u_{i,l})} \right)$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$\beta_{i,j}$</td>
<td>데이터 $j$가 받는 <strong>최종 관심도</strong> (학습 시 사용)</td>
</tr>
<tr>
<td>$W$</td>
<td>한 번에 살펴보는 <strong>청크 크기</strong></td>
</tr>
<tr>
<td>$k$</td>
<td>단조 어텐션이 <strong>멈춘 위치</strong></td>
</tr>
<tr>
<td>$\alpha_{i,k}$</td>
<td>정확히 $k$에서 <strong>멈출 확률</strong></td>
</tr>
<tr>
<td>$\exp(u_{i,j}) / \sum \exp$</td>
<td>청크 안에서 $j$가 <strong>차지하는 비중</strong></td>
</tr>
</tbody></table>
<blockquote>
<p><strong>이 수식이 필요한 이유:</strong><br>테스트 시에는 확률이 0.5 이상인 지점에서 딱 멈추면 됩니다. 하지만 학습 시에는 &quot;멈추는 행동&quot;이 불연속적이라 미분이 불가능합니다. $\beta_{i,j}$는 &quot;평균적으로 $j$를 얼마나 보게 되는가&quot;라는 기댓값을 연속 확률로 표현해서 역전파(Backpropagation)가 가능하게 만듭니다.</p>
</blockquote>
<h4 id="movingsum을-활용한-효율적-계산">MovingSum을 활용한 효율적 계산</h4>
<p>중첩 합산($\sum$ 안에 $\sum$)은 계산 비용이 매우 높습니다. 논문은 이를 <strong>이동 합산(MovingSum)</strong> 을 이용한 병렬 계산으로 해결합니다.</p>
<p>$$\beta_{i,:} = \exp(u_{i,:}) \odot MovingSum\left(\frac{\alpha_{i,:}}{MovingSum(\exp(u_{i,:}), w, 1)}, 1, w\right)$$</p>
<p>이는 길이 $w$의 1 시퀀스와의 컨볼루션으로 구현됩니다. 중첩 반복문 없이 GPU에서 병렬로 계산할 수 있습니다.</p>
<hr>
<h3 id="📊-figure-1--세-가지-어텐션-메커니즘-비교-다이어그램">📊 Figure 1 — 세 가지 어텐션 메커니즘 비교 다이어그램</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/7d96cc10-666d-476d-b848-d45df72b37ec/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 가로축은 메모리(인코더 은닉 상태), 세로축은 출력 타임스텝. 각 노드가 해당 메모리 위치를 해당 출력 시각에 참조할 가능성을 나타냅니다. (a) 소프트 어텐션 — 모든 노드에 회색 음영으로 확률 할당. (b) 하드 단조 어텐션 — 선택된 노드(검은 점)와 건너뛴 노드(×)로 표시. (c) MoChA — 굵은 테두리의 멈춤 지점과 점선으로 표시된 청크 경계, 청크 내 소프트 어텐션 음영.</li>
<li><strong>핵심 메시지:</strong> MoChA의 청크 경계(점선)가 멈춤 위치에 따라 유동적으로 이동합니다. 청크 크기 $w=3$이면 멈춘 위치 기준으로 직전 3개를 묶습니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>세 그림을 나란히 보면 MoChA가 (b)의 확장임이 명확하게 보입니다. (b)에서 검은 점 하나만 참조하던 것을, (c)에서 그 점을 포함한 직전 $w$개 영역으로 넓혔습니다. 구조 변경은 최소인데 정보 활용은 $w$배 늘었습니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--음성-인식-어텐션-정렬-시각화">📊 Figure 2 — 음성 인식 어텐션 정렬 시각화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/927ec00f-3c29-41ea-8d16-1c19fbd041c4/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> WSJ 데이터셋의 실제 음성 발화에 대해 소프트 어텐션(Softmax), 단조 어텐션(Monotonic), MoChA($w=2$) 세 가지의 정렬 히트맵. 가로축은 입력 오디오 특징 시퀀스, 세로축은 출력 문자.</li>
<li><strong>핵심 메시지:</strong> 세 가지 어텐션 모두 왼쪽 아래에서 오른쪽 위로 향하는 <strong>대각선(단조적) 패턴</strong>이 유사하게 나타납니다. MoChA($w=2$)도 소프트 어텐션과 거의 동일한 정렬을 학습했습니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>$w=2$라는 아주 작은 청크 크기만으로도 소프트 어텐션과 시각적으로 거의 동일한 정렬이 만들어진다는 점이 놀랍습니다. 정렬 품질을 유지하는 데 긴 문맥이 반드시 필요한 게 아니라, <strong>직전 2개의 추가 정보</strong>만으로 충분하다는 것을 시각적으로 증명합니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 두 가지 매우 다른 태스크에서 MoChA를 검증했습니다. 하나는 단조 정렬이 자연스러운 음성 인식, 다른 하나는 비단조 정렬이 필요한 문서 요약입니다.</p>
<h3 id="실험-설계">실험 설계</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>음성 인식</th>
<th>문서 요약</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>Wall Street Journal (WSJ)</td>
<td>CNN/Daily Mail</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>WER (낮을수록 우수)</td>
<td>ROUGE F-score (높을수록 우수)</td>
</tr>
<tr>
<td><strong>청크 크기 $w$</strong></td>
<td>2, 3, 4, 6, 8 모두 유사 → <strong>$w=2$ 선택</strong></td>
<td>$w=8$이 최적</td>
</tr>
<tr>
<td><strong>비교 기준</strong></td>
<td>같은 하이퍼파라미터, 어텐션만 교체</td>
<td>같은 하이퍼파라미터, 어텐션만 교체</td>
</tr>
</tbody></table>
<h3 id="음성-인식-결과-table-1-wsj-테스트셋-wer">음성 인식 결과 (Table 1: WSJ 테스트셋 WER)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>Best WER</th>
<th>Average WER</th>
</tr>
</thead>
<tbody><tr>
<td>CTC 기반 [Raffel et al.]</td>
<td>33.4%</td>
<td>—</td>
</tr>
<tr>
<td>강화학습 [Luo et al.]</td>
<td>27.0%</td>
<td>—</td>
</tr>
<tr>
<td>CTC [Wang et al.]</td>
<td>22.7%</td>
<td>—</td>
</tr>
<tr>
<td>하드 단조 어텐션</td>
<td>17.4%</td>
<td>—</td>
</tr>
<tr>
<td>Soft Attention (오프라인)</td>
<td>14.2%</td>
<td>14.6 ± 0.3%</td>
</tr>
<tr>
<td><strong>MoChA, $w=2$</strong></td>
<td><strong>13.9%</strong> ✅</td>
<td>15.0 ± 0.6%</td>
</tr>
</tbody></table>
<h3 id="문서-요약-결과-table-2-cnndaily-mail-rouge-f-score">문서 요약 결과 (Table 2: CNN/Daily Mail ROUGE F-score)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>ROUGE-1</th>
<th>ROUGE-2</th>
</tr>
</thead>
<tbody><tr>
<td>소프트 어텐션 (오프라인)</td>
<td>39.11</td>
<td>15.76</td>
</tr>
<tr>
<td><strong>MoChA, $w=8$</strong></td>
<td><strong>35.46</strong></td>
<td><strong>13.55</strong></td>
</tr>
<tr>
<td>하드 단조 어텐션</td>
<td>31.14</td>
<td>11.16</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>음성 인식에서 MoChA($w=2$)는 <strong>온라인 모델로는 최초로 오프라인 소프트 어텐션과 동등한 성능을 달성</strong>했습니다. SOTA 대비 20% 상대적 WER 개선입니다. 문서 요약에서는 단조 정렬이 없는 태스크임에도 하드 단조 어텐션과 소프트 어텐션 사이의 격차를 <strong>절반 이상 메웠습니다(ROUGE-1 기준 4.32점 회복).</strong></p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>정확도 격차 해소</strong> — 온라인 모델 최초로 오프라인 소프트 어텐션과 동등한 성능을 증명했습니다.</li>
<li><strong>미래 차단</strong> — 왼→오 단방향 스캔을 유지하므로 미래 정보를 절대 참조하지 않습니다. 완벽한 실시간 서비스가 가능합니다.</li>
<li><strong>최소한의 비용</strong> — 파라미터 1% 증가, 런타임 복잡도는 상수 인자 $w$만큼만 늘어납니다.</li>
<li><strong>수학적 우아함</strong> — 불연속 멈춤 결정을 $\beta_{i,j}$라는 기댓값 공식으로 변환해 표준 역전파 학습이 가능합니다.</li>
<li><strong>비단조 태스크에도 유효</strong> — 문서 요약처럼 정렬이 뒤바뀌는 태스크에서도 하드 단조 어텐션 대비 큰 개선을 보였습니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>고정된 청크 크기</strong> — 말의 속도나 언어 특성에 맞춰 $w$를 유동적으로 바꾸지 못합니다. 논문 저자 스스로 &quot;향후 $w$를 적응적으로 변화시키는 연구가 필요하다&quot;고 언급했습니다.</li>
<li><strong>학습 시 비선형 비용</strong> — 테스트 시에는 빠르지만, 학습 시 $\beta_{i,j}$ 계산에 MovingSum 연산이 추가되어 메모리와 연산량이 더 필요합니다.</li>
<li><strong>미래 정보 완전 포기</strong> — $w$개의 과거 프레임만 보기 때문에, 아주 조금의 Look-ahead(미래 엿보기)가 허용되는 환경에서는 성능을 더 끌어올릴 여지가 있습니다.</li>
<li><strong>분산이 약간 높음</strong> — 8회 반복 실험에서 MoChA의 평균 WER(15.0 ± 0.6%)이 소프트 어텐션(14.6 ± 0.3%)보다 분산이 컸습니다. 재현성이 약간 불안정합니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<ol>
<li><strong>Dynamic MoChA</strong> — 상황에 따라 컴퓨터가 청크 크기를 스스로 조절하게 만듭니다. 말이 빠를 때는 작게, 느릴 때는 크게 유동적으로 변합니다.</li>
<li><strong>Look-ahead MoChA</strong> — 0.1초처럼 사용자가 불편하지 않을 아주 짧은 지연만 허용하고 미래 프레임 몇 개를 힌트로 씁니다. 정확도가 더 올라갑니다.</li>
<li><strong>Multi-Head MoChA</strong> — 짧은 청크($w=2$)와 긴 청크($w=8$)를 동시에 여러 헤드에 적용합니다. 짧은 음향 패턴과 긴 언어 문맥을 동시에 잡아냅니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>모델이 똑똑해지려면 더 넓은 시야가 필요하다고 생각했습니다. 하지만 MoChA는 <strong>직전 2개 프레임만 추가로 보는 것</strong>으로 오프라인 소프트 어텐션과 동등한 성능을 달성했습니다. 정보의 양보다 <strong>어떤 정보를 언제 참조하느냐</strong>가 더 중요하다는 것을 배웠습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>불연속적인 결정(멈추거나/멈추지 않거나)은 미분이 불가능하니 학습 자체가 안 된다고 생각했습니다.</p>
<blockquote>
<p><strong>하지만 $\beta_{i,j}$라는 기댓값 공식이 이 문제를 우회했습니다.</strong> &quot;어디서 멈출지&quot;라는 이진 결정을 &quot;평균적으로 어디를 얼마나 볼 것인가&quot;라는 연속 확률로 바꾸니 역전파가 가능해졌습니다. 불연속 문제를 기댓값으로 우회하는 수학적 트릭이 인상 깊었습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>온디바이스 실시간 회의록 자동 생성 시나리오에서 MoChA가 실용적인 선택지가 될 것 같습니다. 특히 $w=2$라는 작은 청크 크기가 소프트 어텐션과 동등한 성능을 낸다는 점은, 제한된 메모리의 스마트폰에서도 충분히 돌릴 수 있는 경량 설계의 가능성을 시사합니다. Dynamic MoChA를 결합해 말이 끊기는 구간에서는 $w$를 줄여 지연을 최소화하는 방향이 흥미로울 것 같습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>소프트 어텐션은 실시간 불가($O(TU)$), 하드 단조 어텐션은 단일 프레임 참조로 정확도 하락</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>단조 스캔으로 멈춤 위치 결정 + 직전 $w$개 청크에 소프트 어텐션 추가</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>WSJ 음성 인식에서 온라인 모델 최초로 오프라인 소프트 어텐션과 동등한 WER 달성 (13.9% vs 14.2%)</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>불연속 결정을 $\beta_{i,j}$ 기댓값 공식으로 변환해 역전파를 가능하게 만든 수학적 우아함</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>청크 크기 $w$가 고정, MoChA 평균 WER의 분산이 소프트 어텐션보다 약간 높음</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>Dynamic $w$ 적응, Look-ahead 허용, Multi-Head MoChA로 다중 해상도 문맥 포착</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>MoChA는 왼쪽에서 오른쪽으로만 달리면서 멈추는 순간 직전 2~8개를 되돌아보는 단 하나의 아이디어로, 실시간 온라인 모델 최초로 오프라인 소프트 어텐션의 정확도를 따라잡은 어텐션 메커니즘의 우아한 타협점이다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Transformer Transducer]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Transformer-Transducer</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Transformer-Transducer</guid>
            <pubDate>Sun, 08 Mar 2026 02:09:29 GMT</pubDate>
            <description><![CDATA[<h3 id="transformer-transducerhttpsarxivorgpdf200202562">Transformer Transducer(<a href="https://arxiv.org/pdf/2002.02562">https://arxiv.org/pdf/2002.02562</a>)</h3>
<h4 id="트랜스포머의-똑똑함--rnn-t의-실시간성--두-마리-토끼를-동시에-잡다">트랜스포머의 똑똑함 + RNN-T의 실시간성 — 두 마리 토끼를 동시에 잡다</h4>
<blockquote>
<p>RNN-T의 뼈대는 그대로 유지하면서 내부 엔진을 LSTM에서 Transformer로 교체하고,<br><strong>어텐션 마스킹으로 시야를 제한해 실시간 스트리밍까지 가능하게 만든 종단간 음성 인식 모델.</strong><br>ICASSP 2020 | Qian Zhang, Han Lu, Hasim Sak, Anshuman Tripathi, Erik McDermott, Stephen Koo, Shankar Kumar (Google Inc.)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 음성 인식 분야의 오래된 딜레마를 정면으로 파고듭니다.</p>
<p><strong>&quot;모델이 똑똑해질수록 실시간 처리가 불가능해진다.&quot;</strong></p>
<p>트랜스포머는 자기 어텐션(Self-Attention) 덕분에 문맥 파악 능력이 매우 뛰어납니다. 하지만 전체 입력을 한꺼번에 봐야 하는 구조라 말이 끝날 때까지 기다려야 합니다. 반면 기존의 실시간 모델(RNN-T)은 속도는 빠르지만 LSTM의 한계로 정확도가 낮습니다.</p>
<p>이 논문은 <strong>RNN-T의 프레임 동기식 뼈대를 그대로 살리면서, 내부 LSTM 인코더를 Transformer로 교체</strong>하는 방법을 제안합니다. 그리고 어텐션 마스킹으로 시야를 제한해 실시간 처리까지 가능하게 만들었습니다. 이 글을 끝까지 읽으시면, 어떻게 &#39;제한된 시야&#39;가 실시간성과 정확도를 동시에 달성하는 열쇠가 되는지 직관적으로 이해하게 되실 겁니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이 연구가 등장했는지 배경을 짚어봅니다.</p>
<h3 id="종단간end-to-end-음성-인식의-3가지-흐름">종단간(End-to-End) 음성 인식의 3가지 흐름</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>대표 논문</th>
<th>장점</th>
<th>치명적 한계</th>
</tr>
</thead>
<tbody><tr>
<td><strong>CTC</strong></td>
<td>Graves et al., 2006</td>
<td>빠르고 간단</td>
<td>출력 간 조건부 독립, 문맥 파악 불가</td>
</tr>
<tr>
<td><strong>LAS (Seq2Seq)</strong></td>
<td>Chan et al., 2015</td>
<td>문맥 파악 우수</td>
<td>발화 끝까지 기다려야 함 — 실시간 불가</td>
</tr>
<tr>
<td><strong>RNN-T</strong></td>
<td>Graves, 2012</td>
<td>실시간 + 문맥 고려</td>
<td>LSTM의 장거리 의존성 한계</td>
</tr>
</tbody></table>
<h3 id="rnn-t-실시간의-영웅-하지만-구형-엔진">RNN-T: 실시간의 영웅, 하지만 구형 엔진</h3>
<p>RNN-T는 스마트폰 음성 비서처럼 <strong>프레임 동기식(Frame-synchronous)</strong> 으로 작동합니다. 매 프레임마다 출력을 뱉을 수 있어 지연이 없습니다. 하지만 내부 인코더가 LSTM이라 긴 문맥을 기억하는 데 한계가 있었습니다.</p>
<h3 id="transformer-최강의-엔진-하지만-실시간-불가">Transformer: 최강의 엔진, 하지만 실시간 불가</h3>
<p>Transformer의 Self-Attention은 입력 전체를 한꺼번에 보면서 어디에 집중할지 결정합니다. 이 능력이 탁월한 성능의 비결이지만, 동시에 <strong>&quot;미래의 소리를 먼저 알아야 한다&quot;</strong> 는 구조적 문제를 만들었습니다.</p>
<blockquote>
<p><strong>이 논문이 풀려는 핵심 질문:</strong><br>Transformer의 자기 어텐션을 실시간 환경에서 작동하게 만들 수 있을까?<br>그리고 RNN-T의 프레임 동기식 손실 함수와 결합할 수 있을까?</p>
</blockquote>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 두 가지입니다.</p>
<table>
<thead>
<tr>
<th>문제</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Transformer의 비인과성</strong></td>
<td>Self-Attention이 미래 프레임까지 참조 → 발화가 끝나야만 처리 가능</td>
</tr>
<tr>
<td><strong>Self-Attention의 이차 복잡도</strong></td>
<td>입력 길이 $T$에 대해 $O(T^2)$ 계산 → 스트리밍 환경에서 프레임당 연산량이 계속 늘어남</td>
</tr>
</tbody></table>
<h3 id="직관적-비유-🔦">직관적 비유 🔦</h3>
<p>동굴을 탐험한다고 상상해 봅시다.</p>
<ul>
<li><strong>기존 Transformer:</strong> 동굴 전체에 조명을 설치한 뒤 전부 살펴보고 길을 정합니다. 정확하지만 조명 설치가 끝날 때까지 기다려야 합니다.</li>
<li><strong>RNN-T (LSTM):</strong> 손전등 하나로 앞만 보며 걷습니다. 빠르지만 멀리 있는 장애물을 미리 파악하지 못합니다.</li>
<li><strong>Transformer Transducer:</strong> 손전등으로 앞 10걸음만 비추며 걷습니다. 속도를 유지하면서도 LSTM보다 훨씬 넓은 문맥을 파악합니다.</li>
</ul>
<blockquote>
<p><strong>핵심 아이디어:</strong><br>어텐션이 볼 수 있는 범위를 고정 윈도우로 제한(마스킹)하면, 프레임당 연산량이 $O(W)$로 상수화되어 스트리밍이 가능해집니다.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>Transformer Transducer(T-T)는 <strong>RNN-T의 뼈대 + Transformer 인코더 + 제한적 어텐션 마스킹</strong> 세 요소의 결합으로 작동합니다.</p>
<h3 id="전체-구조-rnn-t-아키텍처에-transformer를-이식">전체 구조: RNN-T 아키텍처에 Transformer를 이식</h3>
<p>$$Joint = Linear(AudioEncoder_{t_i}(x)) + Linear(LabelEncoder(Labels_{z_{1:(i-1)}}))$$</p>
<p>$$P(z_i|x, t_i, Labels_{z_{1:(i-1)}}) = Softmax(Linear(\tanh(Joint)))$$</p>
<p>RNN-T 구조는 <strong>오디오 인코더, 라벨 인코더, 조인트 네트워크</strong> 세 부분으로 나뉩니다. 기존 RNN-T는 두 인코더 모두 LSTM이었습니다. T-T는 이 두 인코더를 <strong>Transformer로 교체</strong>합니다.</p>
<table>
<thead>
<tr>
<th>구성 요소</th>
<th>기존 RNN-T</th>
<th>Transformer Transducer</th>
</tr>
</thead>
<tbody><tr>
<td>오디오 인코더</td>
<td>LSTM</td>
<td>Transformer (18 layers)</td>
</tr>
<tr>
<td>라벨 인코더</td>
<td>LSTM</td>
<td>Transformer (2 layers)</td>
</tr>
<tr>
<td>조인트 네트워크</td>
<td>Feed-Forward</td>
<td>Feed-Forward (동일)</td>
</tr>
<tr>
<td>손실 함수</td>
<td>RNN-T Loss</td>
<td>RNN-T Loss (동일)</td>
</tr>
</tbody></table>
<h3 id="핵심-설계-transformer-인코더-블록">핵심 설계: Transformer 인코더 블록</h3>
<p>논문의 Transformer 인코더는 일반적인 Transformer와 미묘하게 다릅니다.</p>
<ol>
<li><strong>LayerNorm 먼저 적용</strong> — 입력에 먼저 정규화한 뒤 어텐션 계산 (Pre-Norm 방식)</li>
<li><strong>상대적 위치 인코딩(Relative Positional Encoding)</strong> — Transformer-XL 방식을 채택해 <strong>과거에 계산한 상태를 재사용</strong> 가능하게 함. 절대 위치 인코딩을 쓰면 재사용이 불가해 복잡도가 $O(t^2)$로 폭발</li>
<li><strong>라벨 인코더 ↔ 오디오 인코더 간 어텐션 없음</strong> — 두 인코더가 서로를 참조하지 않고 독립적으로 동작 → 스트리밍 가능</li>
</ol>
<blockquote>
<p><strong>왜 라벨 인코더가 오디오 인코더를 보지 않나요?</strong><br>LAS처럼 디코더가 인코더를 참조하는 구조는 오디오 전체를 알아야만 작동합니다. T-T는 정렬(Alignment)을 RNN-T Loss의 Forward 알고리즘이 처리하므로, 두 인코더가 독립적으로 동작해도 됩니다. 이것이 스트리밍을 가능하게 만드는 구조적 비결입니다.</p>
</blockquote>
<h3 id="스트리밍의-열쇠-어텐션-마스킹">스트리밍의 열쇠: 어텐션 마스킹</h3>
<p>Transformer의 Self-Attention을 실시간 환경에 쓰려면 <strong>미래 프레임을 보지 못하게 막아야</strong> 합니다.</p>
<p>$$\text{복잡도: } O(t) \xrightarrow{\text{윈도우 마스킹}} O(W) \text{ (상수)}$$</p>
<table>
<thead>
<tr>
<th>마스킹 방식</th>
<th>설명</th>
<th>지연 시간</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Full Attention</strong></td>
<td>과거·미래 프레임 모두 참조</td>
<td>발화 전체 대기</td>
</tr>
<tr>
<td><strong>Left-only (left=10)</strong></td>
<td>과거 10프레임만 참조</td>
<td>거의 0</td>
</tr>
<tr>
<td><strong>Left + Right Context</strong></td>
<td>과거 N + 미래 M 프레임 참조</td>
<td>레이어 수 × M × 30ms</td>
</tr>
</tbody></table>
<p><strong>Right Context의 트레이드오프:</strong><br>Figure 3이 이를 잘 보여줍니다. 3개 레이어에서 right=1프레임씩 허용하면, $y_7$을 출력하기 위해 실제로는 $x_{10}$이 도착할 때까지 기다려야 합니다. 논문에서 right=6프레임/레이어를 허용하면 약 <strong>3.2초 지연</strong>이 발생하지만 성능이 크게 개선됩니다.</p>
<h3 id="직관적-예시-2가지-💡">직관적 예시 2가지 💡</h3>
<table>
<thead>
<tr>
<th>비유</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>동시통역사</strong></td>
<td>소리 인코더는 귀로 발음만 듣고, 라벨 인코더는 지금까지 적은 자막만 봅니다. 둘의 의견을 조인트 네트워크가 종합해 다음 글자를 결정합니다</td>
</tr>
<tr>
<td><strong>손전등 탐험</strong></td>
<td>Full Attention = 전체 조명 설치 후 출발. Left=10 마스킹 = 손전등으로 10걸음 앞만 비추며 실시간 전진</td>
</tr>
</tbody></table>
<hr>
<h3 id="수식-이해하기">수식 이해하기</h3>
<h4 id="핵심-수식-모든-정렬-경로의-확률-합산">핵심 수식: 모든 정렬 경로의 확률 합산</h4>
<p>$$P(y|x) = \sum_{z \in Z(y,T)} P(z|x)$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$y$</td>
<td>최종 출력 레이블 시퀀스 (예: &quot;hello&quot;)</td>
</tr>
<tr>
<td>$x$</td>
<td>입력 오디오 프레임 시퀀스</td>
</tr>
<tr>
<td>$z$</td>
<td>레이블과 시간의 정렬 쌍 — blank 포함 가능</td>
</tr>
<tr>
<td>$Z(y,T)$</td>
<td>길이 $T$에서 $y$가 될 수 있는 모든 유효 정렬의 집합</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>이 수식의 핵심:</strong><br>CTC와 마찬가지로 가능한 모든 경로의 확률을 합산합니다. CTC와의 차이는 각 경로 확률 $P(z|x)$를 계산할 때 <strong>이전 라벨 히스토리를 조건으로 포함</strong>한다는 점입니다. 즉, 이전에 무엇을 출력했는지가 현재 출력에 영향을 미칩니다.</p>
</blockquote>
<h4 id="self-attention-수식">Self-Attention 수식</h4>
<p>$$Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$Q$ (Query)</td>
<td>지금 집중하려는 기준 벡터</td>
</tr>
<tr>
<td>$K$ (Key)</td>
<td>비교 대상 벡터들의 태그</td>
</tr>
<tr>
<td>$V$ (Value)</td>
<td>실제로 끌어올 정보</td>
</tr>
<tr>
<td>$\sqrt{d_k}$</td>
<td>점수 폭주 방지 스케일링</td>
</tr>
</tbody></table>
<p>스트리밍 모드에서는 $QK^T$ 계산 시 미래 위치를 $-\infty$로 마스킹해 Softmax 후 가중치가 0이 되도록 만듭니다.</p>
<hr>
<h3 id="📊-figure-1--rnn-t-vs-transformer-transducer-아키텍처-비교">📊 Figure 1 — RNN-T vs Transformer Transducer 아키텍처 비교</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/c1d16b7e-34d0-4e6e-8c62-536ec71096b8/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 왼쪽은 LSTM 기반 RNN-T, 오른쪽은 Transformer 인코더로 교체된 T-T의 전체 구조. 오디오 인코더, 라벨 인코더, 조인트 네트워크(Feed-Forward + Softmax) 세 블록 구성이 동일함을 보여줍니다.</li>
<li><strong>핵심 메시지:</strong> 뼈대(RNN-T 구조)는 완전히 동일하고 내부 인코더 블록만 Transformer로 교체되었습니다. 이 심플한 교체가 논문의 핵심 아이디어입니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>두 인코더(오디오, 라벨)가 서로를 참조하지 않고 독립적으로 작동한다는 점이 LAS와 가장 크게 다릅니다. LAS는 디코더가 인코더 전체를 봐야 하지만, T-T는 정렬을 RNN-T Loss가 담당하므로 두 인코더가 분리되어 스트리밍이 가능해집니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--transformer-인코더-블록-내부-구조">📊 Figure 2 — Transformer 인코더 블록 내부 구조</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/9812d35b-4aaa-4ec9-8069-c36e84673590/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> T-T에 쓰인 Transformer 레이어의 세부 구조. 입력 → LayerNorm → Multi-Head Attention → Residual Connection → LayerNorm → Feed-Forward(2048 → 1024) → Residual Connection → 출력. 입력 임베딩 크기 512, 어텐션 헤드 8개, 헤드 차원 64, Dropout 0.1의 파라미터 설정이 Table 1에 명시됩니다.</li>
<li><strong>핵심 메시지:</strong> Pre-Norm(LayerNorm을 먼저 적용) + Residual Connection 구조로 깊은 레이어에서도 안정적으로 학습됩니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>일반적인 Transformer(Post-Norm)와 달리 LayerNorm을 먼저 적용합니다. 또한 상대적 위치 인코딩(Transformer-XL 방식)을 써서 스트리밍 시 이전에 계산한 상태를 재사용할 수 있습니다. 이 덕분에 복잡도가 $O(t^2)$ 에서 $O(t)$로 줄고, 윈도우 마스킹을 더하면 $O(W)$ 상수 복잡도가 됩니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-3--right-context-지연-시간-시각화">📊 Figure 3 — Right Context 지연 시간 시각화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/992b0629-8b07-4870-b6d0-932763999471/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 3개 레이어 Transformer에서 각 레이어에 right=1프레임 허용 시, $y_7$을 출력하려면 실제로 $x_{10}$이 도착할 때까지 기다려야 하는 지연 누적 과정을 다이어그램으로 표현합니다.</li>
<li><strong>핵심 메시지:</strong> 레이어가 많을수록 Right Context의 지연이 누적됩니다. 18개 레이어에서 right=6프레임/레이어 허용 시 약 <strong>3.2초 지연</strong>(18 × 6 × 30ms ≈ 3.24초)이 발생하지만, WER이 크게 개선됩니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>이 그림 하나로 &quot;Right Context 몇 프레임을 허용할 것인가&quot;가 단순한 하이퍼파라미터 선택이 아니라 실제 사용자 체감 지연 시간과 직결된 설계 결정임을 알 수 있습니다. 논문은 right=2프레임/레이어(약 1초 지연)가 스트리밍 모델 대비 약 30% 성능 개선을 가져온다고 밝혔습니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 T-T가 정확도와 실시간성을 동시에 달성하는지 체계적으로 검증했습니다.</p>
<table>
<thead>
<tr>
<th>실험 항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>LibriSpeech (970시간 오디오 + 800M 단어 텍스트 전용 데이터)</td>
</tr>
<tr>
<td><strong>음향 특징</strong></td>
<td>128채널 log-mel, 32ms 윈도우, 4프레임 스태킹 + 3프레임 서브샘플링 → 512차원, 30ms 스트라이드</td>
</tr>
<tr>
<td><strong>모델 구조</strong></td>
<td>오디오 인코더 18레이어 + 라벨 인코더 2레이어, 총 <strong>139M 파라미터</strong></td>
</tr>
<tr>
<td><strong>학습 환경</strong></td>
<td>8×8 TPU, 배치 2048, 약 <strong>1일 학습</strong> (LSTM RNN-T: 3.5일 대비)</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>WER(단어 오류율) — test-clean / test-other</td>
</tr>
</tbody></table>
<h3 id="결과-요약-table-2-기준">결과 요약 (Table 2 기준)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>파라미터</th>
<th>Clean WER</th>
<th>Other WER</th>
<th>LM 적용 시 Clean</th>
<th>LM 적용 시 Other</th>
</tr>
</thead>
<tbody><tr>
<td>Hybrid [22]</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>2.26%</td>
<td>4.85%</td>
</tr>
<tr>
<td>LAS [23]</td>
<td>361M</td>
<td>2.8%</td>
<td>6.8%</td>
<td>2.5%</td>
<td>5.8%</td>
</tr>
<tr>
<td>BiLSTM RNN-T</td>
<td>130M</td>
<td>3.2%</td>
<td>7.8%</td>
<td>—</td>
<td>—</td>
</tr>
<tr>
<td><strong>FullAttn T-T (Ours)</strong></td>
<td><strong>139M</strong></td>
<td><strong>2.4%</strong></td>
<td><strong>5.6%</strong></td>
<td><strong>2.0%</strong></td>
<td><strong>4.6%</strong> ✅</td>
</tr>
</tbody></table>
<h3 id="스트리밍-모드-결과-table-3-4-6-기준">스트리밍 모드 결과 (Table 3, 4, 6 기준)</h3>
<table>
<thead>
<tr>
<th>오디오 Left</th>
<th>Right</th>
<th>라벨 Left</th>
<th>Clean WER</th>
<th>Other WER</th>
</tr>
</thead>
<tbody><tr>
<td>512 (Full)</td>
<td>512</td>
<td>20</td>
<td>2.4%</td>
<td>5.6%</td>
</tr>
<tr>
<td><strong>10</strong></td>
<td><strong>2</strong></td>
<td><strong>2</strong></td>
<td><strong>3.6%</strong></td>
<td><strong>10.0%</strong></td>
</tr>
<tr>
<td>10</td>
<td>0</td>
<td>20</td>
<td>4.2%</td>
<td>11.3%</td>
</tr>
<tr>
<td>6</td>
<td>0</td>
<td>20</td>
<td>4.3%</td>
<td>11.8%</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>Full Attention T-T(2.4%)는 LAS(2.8%, 3.6배 큰 모델)와 BiLSTM RNN-T(3.2%)를 모두 이겼습니다. 파라미터 수는 오히려 더 적으면서 SOTA를 달성했습니다. 스트리밍 모드(left=10, right=2, label=2)에서도 3.6%로, 기존 BiLSTM RNN-T 최고 성적(3.2%)에 근접한 수준을 유지했습니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>학습 속도 3.5배 향상</strong> — 같은 파라미터 수에서 LSTM RNN-T 대비 1일 vs 3.5일. Self-Attention의 병렬화 덕분입니다.</li>
<li><strong>유연한 정확도-지연 트레이드오프</strong> — Left/Right Context 프레임 수와 레이어 수를 조절해 지연 시간과 WER을 자유롭게 균형 잡을 수 있습니다.</li>
<li><strong>적은 파라미터로 SOTA</strong> — 361M의 LAS보다 2.6배 작은 139M으로 더 낮은 WER 달성.</li>
<li><strong>라벨 인코더는 left=3만으로 충분</strong> — Table 5에서 라벨 left를 20→3으로 줄여도 WER 변화가 미미합니다. 라벨 문맥은 오디오보다 훨씬 짧아도 됩니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>스트리밍 시 성능 저하</strong> — Full Attention(2.4%) 대비 Left-only 스트리밍(4.2%)은 WER 75% 상승. 아직 격차가 큽니다.</li>
<li><strong>조용한 환경 편향</strong> — LibriSpeech는 오디오북 기반의 깨끗한 데이터입니다. 지하철·식당 같은 실제 잡음 환경에서의 검증이 빠져 있습니다.</li>
<li><strong>여전히 무거운 모델</strong> — 139M 파라미터는 온디바이스 스마트폰 탑재에는 부담스러운 크기입니다.</li>
<li><strong>같은 마스크를 모든 레이어에 적용</strong> — 논문이 직접 &quot;레이어별로 다른 Context를 쓰는 것이 탐구할 가치가 있다&quot;고 언급할 만큼 아직 최적화되지 않은 설계입니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<ol>
<li><strong>Conformer와 결합</strong> — Convolution 블록을 추가해 지역적 음향 패턴까지 잡으면 WER이 더 낮아집니다. (실제로 이후 Conformer-T 연구로 발전)</li>
<li><strong>Dynamic Chunk 크기</strong> — 말이 빠를 때는 넓게, 말이 멈췄을 때는 좁게 청크를 유동적으로 조절하면 지연-정확도 균형이 개선됩니다.</li>
<li><strong>Knowledge Distillation</strong> — Full Attention 모델이 선생님, 스트리밍 모델이 학생이 되어 미래 문맥을 간접적으로 학습하면 격차를 줄일 수 있습니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>같은 Transformer라도 <strong>어디에 어텐션을 허용하느냐</strong>가 모델의 성격을 완전히 바꾼다는 것을 배웠습니다. Full Attention과 Left-only Masking은 수식 구조가 똑같지만, 마스크 하나로 실시간 모델과 비실시간 모델로 갈립니다. 구조보다 <strong>어떤 정보에 접근을 허용할 것인가</strong>라는 설계 철학이 더 중요하다는 것을 깨달았습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>&quot;실시간 모델은 배치 처리 모델보다 항상 성능이 낮을 것이다&quot;라고 생각했습니다.</p>
<blockquote>
<p>하지만 T-T의 스트리밍 모드(left=10, right=2)는 WER 3.6%로, Full Attention LAS(2.8%)와 오히려 비슷한 수준입니다. <strong>Right Context를 소량 허용하는 것만으로도 Full Attention과의 격차를 상당 부분 메울 수 있다는 사실</strong>이 실용적인 설계 지점으로 남았습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>온디바이스 실시간 회의록 생성 시나리오를 생각해보면, T-T의 레이어별 Context 마스킹 전략을 응용할 수 있을 것 같습니다. 하위 레이어는 넓은 Right Context로 음향 패턴을 충분히 파악하고, 상위 레이어는 Left-only로 지연을 최소화하는 계층별 차등 마스킹 방식이 흥미로운 구조가 될 것 같습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>Transformer는 성능이 뛰어나지만 전체 입력을 봐야 해서 실시간 처리 불가. LSTM RNN-T는 실시간이지만 정확도 한계</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>RNN-T 뼈대 유지 + LSTM → Transformer 교체 + 어텐션 윈도우 마스킹으로 실시간화</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>LibriSpeech SOTA 달성(Clean 2.4%, LM 적용 시 2.0%), LSTM RNN-T 대비 학습 속도 3.5배 향상</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>라벨 인코더가 오디오 인코더를 참조하지 않는 구조 덕분에 스트리밍이 가능해진다는 설계적 통찰</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>스트리밍 모드의 WER 상승(2.4→4.2%), 잡음 환경 검증 부재, 모든 레이어에 동일 마스크 적용</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>Conformer 블록 결합, Dynamic Chunk 마스킹, Full-Streaming Knowledge Distillation</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>Transformer Transducer는 RNN-T의 프레임 동기식 뼈대에 Transformer 인코더를 이식하고 어텐션 윈도우 마스킹으로 시야를 제한해, 전 세계 표준 벤치마크에서 SOTA를 달성하면서도 실시간 스트리밍까지 가능하게 만든 정확도와 실시간성의 균형점이다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Listen, Attend and Spell (LAS)]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Listen-Attend-and-Spell-LAS</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Listen-Attend-and-Spell-LAS</guid>
            <pubDate>Thu, 05 Mar 2026 14:28:50 GMT</pubDate>
            <description><![CDATA[<h3 id="논문-리뷰-listen-attend-and-spell-las-httpsarxivorgpdf150801211">[논문 리뷰] Listen, Attend and Spell (LAS) (<a href="https://arxiv.org/pdf/1508.01211">https://arxiv.org/pdf/1508.01211</a>)</h3>
<h4 id="발음-사전-없이-소리를-문자로-번역하는-종단간-음성-인식의-탄생">발음 사전 없이 소리를 문자로 번역하는 종단간 음성 인식의 탄생</h4>
<blockquote>
<p>수천 프레임의 오디오를 피라미드로 압축하고, 어텐션으로 한 글자씩 집중해서 읽어내는<br><strong>단일 신경망 하나로 전통적 음성 인식 파이프라인 전체를 대체한 혁명적 아키텍처.</strong><br>ICLR 2016 | William Chan (CMU), Navdeep Jaitly, Quoc V. Le, Oriol Vinyals (Google Brain)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 음성 인식 시스템이 <strong>&#39;생각보다 훨씬 복잡한 사전 준비를 요구해왔다&#39;</strong> 는 불편한 진실을 정면으로 파고든 연구입니다.</p>
<p>전통적인 음성 인식 시스템은 음향 모델, 발음 사전, 언어 모델 등 여러 독립된 모듈의 복잡한 결합체입니다. 각 모듈을 독립적으로 설계하고 훈련해야 하므로 고도의 전문 지식이 필요합니다. 새로운 언어나 환경에 적용할 때마다 번거로운 튜닝 과정을 거쳐야 합니다. 이러한 구조는 전체 시스템을 한 번에 최적화하는 데 방해가 됩니다.</p>
<p>이 논문은 이 모든 파이프라인을 <strong>Listen, Attend and Spell(LAS)</strong> 이라는 단일 딥러닝 아키텍처 하나로 통합합니다. 이 글을 끝까지 읽으시면, 어떻게 신경망 하나가 발음 사전도, HMM도 없이 오디오를 곧바로 문자로 바꿔내는지 그 직관적인 원리를 깨닫게 되실 겁니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이런 연구가 필요했는지 배경지식을 가볍게 짚고 넘어가 봅시다.</p>
<h3 id="음성-인식의-기존-흐름">음성 인식의 기존 흐름</h3>
<table>
<thead>
<tr>
<th>세대</th>
<th>방식</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><strong>GMM-HMM</strong></td>
<td>통계 기반 음향·언어 모델 결합</td>
<td>전문 지식 필수, 먼 문맥 기억 불가</td>
</tr>
<tr>
<td><strong>DNN-HMM</strong></td>
<td>딥러닝을 음향 모델에 적용</td>
<td>HMM의 한계 그대로 상속, 파편화 훈련</td>
</tr>
<tr>
<td><strong>CTC 기반</strong></td>
<td>분절 없이 종단간 학습</td>
<td>출력 간 조건부 독립 가정이 치명적 약점</td>
</tr>
<tr>
<td><strong>LAS (이 논문)</strong></td>
<td>Seq2Seq + 어텐션 기반 종단간</td>
<td>조건부 독립 가정 폐기, 완전 통합</td>
</tr>
</tbody></table>
<h3 id="ctc의-한계와-las의-등장">CTC의 한계와 LAS의 등장</h3>
<p>직전 논문인 CTC는 수작업 분절 없이 학습한다는 혁신을 이뤄냈습니다. 하지만 결정적인 약점이 남아 있었습니다.</p>
<blockquote>
<p><strong>CTC의 치명적 가정:</strong> &quot;이 프레임에서 &#39;a&#39;가 나올 확률은 이전에 &#39;c&#39;, &#39;a&#39;, &#39;t&#39;가 나왔는지와 완전히 독립적이다.&quot;</p>
</blockquote>
<p>이 가정 때문에 CTC는 언어 모델을 스스로 내재화하지 못했습니다. LAS는 이 가정을 완전히 폐기하여 다음 문자 예측이 이전 문자들에 의존하도록 설계했습니다.</p>
<h3 id="또-다른-도전-오디오의-압도적인-길이">또 다른 도전: 오디오의 압도적인 길이</h3>
<p>기계 번역에서 성공한 Seq2Seq + 어텐션 구조를 음성에 바로 적용하면 문제가 생깁니다.</p>
<blockquote>
<p>오디오 신호는 수백에서 수천 개의 프레임으로 이루어집니다. 디코더가 한 글자를 예측할 때마다 이 수천 개를 전부 훑어야 하므로 모델이 어디를 봐야 할지 길을 잃어 수렴하지 못합니다.</p>
</blockquote>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;기존 파이프라인은 너무 파편화되어 있고, 통합하려면 새로운 구조적 돌파구가 필요하다&quot;</strong> 는 것입니다.</p>
<h3 id="기존-방식의-3가지-한계">기존 방식의 3가지 한계</h3>
<table>
<thead>
<tr>
<th>문제</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>파이프라인 파편화</strong></td>
<td>음향·발음·언어 모델을 각각 별도 목표로 따로 훈련 → 최적화 오류 누적</td>
</tr>
<tr>
<td><strong>조건부 독립의 한계</strong></td>
<td>CTC는 출력 문자들이 서로 독립적이라 가정 → 언어 문맥 자가 학습 불가</td>
</tr>
<tr>
<td><strong>어텐션 연산 폭발</strong></td>
<td>수천 프레임 오디오에 어텐션을 직접 적용하면 디코더가 수렴 실패</td>
</tr>
</tbody></table>
<h3 id="직관적-비유-🏢">직관적 비유 🏢</h3>
<p>회사 보고 체계로 비유해 봅시다.</p>
<ul>
<li><strong>기존 방식:</strong> 음향 분석팀, 발음 사전팀, 언어 교정팀이 따로 존재합니다. 각 팀이 순서대로 보고서를 넘기다 보니 오류가 누적되고 전체 최적화가 불가능합니다.</li>
<li><strong>LAS:</strong> 한 명의 만능 비서(단일 신경망)가 소리를 들으면서 동시에 문법도 챙기고 글자도 적어냅니다. 사장(정답)에게 단 하나의 보고서만 올라갑니다.</li>
</ul>
<blockquote>
<p><strong>이 문제를 해결하면</strong><br>오직 오디오-텍스트 쌍 데이터만 있으면 발음 사전도, HMM도, 별도 언어 모델도 없이 처음부터 끝까지(End-to-End) 단번에 학습이 가능해집니다.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>LAS는 <strong>Listen(듣기) → Attend(집중) → Spell(적기)</strong> 세 단계로 작동합니다.</p>
<h3 id="전체-작동-흐름">전체 작동 흐름</h3>
<p>$$h = Listen(x)$$
$$P(y|x) = AttendAndSpell(h, y)$$</p>
<ol>
<li><strong>Listen</strong> — 피라미드형 양방향 LSTM(pBLSTM)이 긴 오디오를 압축된 고차원 벡터 시퀀스 $h$로 변환합니다.</li>
<li><strong>Attend</strong> — 디코더(스펠러)가 현재 상태와 $h$를 비교해 어느 시간대에 집중할지 가중치를 계산합니다.</li>
<li><strong>Spell</strong> — 집중 가중치로 만든 컨텍스트 벡터를 바탕으로 다음 문자의 확률 분포를 출력합니다.</li>
</ol>
<h3 id="listen-피라미드형-압축">Listen: 피라미드형 압축</h3>
<p><strong>기본 BLSTM vs pBLSTM</strong></p>
<p>$$h_i^j = BLSTM(h_{i-1}^j,\ h_i^{j-1}) \quad \text{(일반 BLSTM)}$$</p>
<p>$$h_i^j = pBLSTM(h_{i-1}^j,\ [h_{2i}^{j-1},\ h_{2i+1}^{j-1}]) \quad \text{(피라미드 BLSTM)}$$</p>
<p>핵심 차이는 괄호 안입니다. 아랫층의 <strong>인접한 두 타임스텝을 하나로 합쳐</strong> 윗층에 넘깁니다. 층을 올라갈 때마다 길이가 절반씩 줄어듭니다.</p>
<table>
<thead>
<tr>
<th>층</th>
<th>프레임 수</th>
</tr>
</thead>
<tbody><tr>
<td>입력</td>
<td>1,000개</td>
</tr>
<tr>
<td>pBLSTM 1층</td>
<td>500개</td>
</tr>
<tr>
<td>pBLSTM 2층</td>
<td>250개</td>
</tr>
<tr>
<td><strong>pBLSTM 3층</strong></td>
<td><strong>125개</strong> (8배 압축)</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>비유: 회사 보고 압축</strong><br>평사원 8명의 보고서 → 대리 4명이 2장씩 묶어 요약 → 과장 2명이 재요약 → 부장 1명이 최종 1장으로 압축해 사장에게 전달. 사장이 검토해야 할 서류가 8배 줄어들었습니다.</p>
</blockquote>
<p>논문 실험에서 pBLSTM 없이 일반 BLSTM만 사용하면 <strong>한 달을 학습해도 수렴하지 못했습니다.</strong> pBLSTM이 없으면 LAS 자체가 작동하지 않는다는 뜻입니다.</p>
<h3 id="attend--spell-집중과-받아쓰기">Attend &amp; Spell: 집중과 받아쓰기</h3>
<p><strong>수식 이해하기</strong></p>
<p>$$e_{i,u} = \langle \phi(s_i),\ \psi(h_u) \rangle$$</p>
<p>$$\alpha_{i,u} = \frac{\exp(e_{i,u})}{\sum_u \exp(e_{i,u})}$$</p>
<p>$$c_i = \sum_u \alpha_{i,u}\ h_u$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$s_i$</td>
<td>현재 디코더(스펠러)의 상태</td>
</tr>
<tr>
<td>$h_u$</td>
<td>인코더(리스너)가 뽑아낸 $u$번째 오디오 벡터</td>
</tr>
<tr>
<td>$e_{i,u}$</td>
<td>$s_i$와 $h_u$ 사이의 유사도(궁합 점수)</td>
</tr>
<tr>
<td>$\alpha_{i,u}$</td>
<td>0~1 사이로 정규화된 집중 가중치</td>
</tr>
<tr>
<td>$c_i$</td>
<td>가중치에 따라 혼합된 최종 컨텍스트 벡터</td>
</tr>
<tr>
<td>$\phi,\ \psi$</td>
<td>각각 디코더·인코더 상태를 변환하는 MLP</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>비유: 동시통역사의 귀</strong><br>통역사가 &quot;사과&quot;를 말해야 할 타이밍이 됩니다. 화자가 말한 수백 개의 단어 중 &quot;Apple&quot;이라는 소리 파형에만 귀를 쫑긋 세워 집중($\alpha$ 값이 높아짐)합니다. 나머지 소리는 흐릿하게 처리하고, 그 집중된 정보($c_i$)를 바탕으로 &quot;사과&quot;를 받아적습니다.</p>
</blockquote>
<p><strong>계산 예시:</strong><br>오디오가 3프레임($h_1, h_2, h_3$)으로 압축되었습니다. 현재 상태($s$)와 비교한 에너지가 [1, 5, 0]이라면, softmax를 거치면 대략 <strong>[0.01, 0.98, 0.01]</strong> 이 됩니다. 즉 2번째 오디오 프레임을 98% 활용해 컨텍스트 벡터를 만들어 다음 글자를 예측합니다.</p>
<h3 id="학습의-핵심-sampling-trick">학습의 핵심: Sampling Trick</h3>
<p>학습 중에는 이전 스텝의 <strong>정답 문자</strong>를 다음 입력으로 씁니다. 하지만 실제 추론 때는 모델이 스스로 예측한 문자를 다음 입력으로 써야 합니다. 이 훈련-추론 간의 괴리가 오류를 증폭시킵니다.</p>
<p>저자들은 이를 해결하기 위해 <strong>10% 확률로 이전 정답 대신 모델 예측값을 입력</strong>하는 Sampling Trick을 도입했습니다. 이 트릭 하나로 WER이 16.2% → <strong>14.1%</strong> 로 떨어졌습니다.</p>
<hr>
<h3 id="📊-figure-1--las-전체-아키텍처-다이어그램">📊 Figure 1 — LAS 전체 아키텍처 다이어그램</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/a5a9310e-8488-49d0-8255-cfaf012a2c6e/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 왼쪽의 리스너(피라미드 BLSTM)가 긴 입력 $x$를 짧은 $h$로 압축하는 과정과, 오른쪽의 스펠러(어텐션 기반 디코더)가 $h$를 참조해 문자 $y$를 하나씩 출력하는 전체 흐름. pBLSTM이 층을 올라갈수록 타임스텝이 줄어드는 피라미드 형태가 시각적으로 표현되어 있습니다.</li>
<li><strong>핵심 메시지:</strong> 리스너와 스펠러가 완전히 분리된 두 모듈이 아니라, 어텐션 컨텍스트 벡터 $c_i$를 통해 매 문자 출력 때마다 긴밀하게 연결되어 함께 작동하는 구조입니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>그림을 보면 스펠러가 문자를 하나 출력할 때마다 $h$ 전체에 어텐션을 다시 계산합니다. 즉 &quot;A&quot;를 쓸 때와 &quot;p&quot;를 쓸 때 집중하는 오디오 구간이 매번 달라집니다. 이것이 CTC와 결정적으로 다른 점이며, 언어 문맥을 스스로 학습하는 원동력입니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--어텐션-정렬-시각화">📊 Figure 2 — 어텐션 정렬 시각화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/4c9de9bd-8e39-4cf1-a088-69e65d9ea2b1/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> &quot;how much would a woodchuck chuck&quot;라는 발화에 대해, 가로축은 오디오 필터뱅크 타임스텝, 세로축은 출력 문자 순서를 나타내는 히트맵. 밝은 색일수록 해당 오디오 구간에 강하게 집중했다는 뜻입니다.</li>
<li><strong>핵심 메시지:</strong> 어텐션 정렬이 <strong>왼쪽 아래에서 오른쪽 위로 향하는 대각선(단조적) 패턴</strong>을 보입니다. 위치 기반 사전 정보(Location Prior) 없이도 모델이 스스로 순서대로 집중하는 법을 학습했습니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>&quot;woodchuck&quot;과 &quot;chuck&quot;는 발음이 유사해서 해당 구간에서 어텐션 분포가 살짝 흐릿해집니다. 논문이 정직하게 이 한계를 시각화로 공개한 점이 인상적입니다. 또한 발화의 시작점과 끝점도 정확히 찾아냈습니다. 위치 정보를 강제로 넣지 않아도 내용 기반 어텐션만으로 정렬이 된다는 사실이 경이롭습니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-3--빔-너비beam-width에-따른-wer-변화">📊 Figure 3 — 빔 너비(Beam Width)에 따른 WER 변화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/36be32fe-2349-4ba0-9282-68eb03de9372/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> X축은 빔 서치의 너비($\beta$), Y축은 WER(단어 오류율). 언어 모델 없는 경우(WER), 언어 모델 재채점 적용 경우(WER LM), 이론적 최상값(WER Oracle) 세 가지 곡선을 비교합니다.</li>
<li><strong>핵심 메시지:</strong> 빔 너비가 1에서 16으로 커지는 구간에서 WER이 빠르게 개선됩니다. 16 이상에서는 추가 이득이 미미합니다. 빔 너비 32에서 WER 14.1%(LM 없음), 10.3%(LM 적용)를 달성했습니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>Oracle WER이 4.3%라는 것은 &quot;모델이 이미 정답을 32개 후보 안에 담고 있다&quot;는 의미입니다. 즉 모델 자체의 음향 학습 능력은 충분하며, 언어 모델을 더 정교하게 만들면 최종 성능 향상 여지가 크다는 것을 보여줍니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-4--발화-길이에-따른-오류-유형-분석">📊 Figure 4 — 발화 길이에 따른 오류 유형 분석</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/76170878-7271-4fa0-b506-afb93b0e875c/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> X축은 발화 내 단어 수, Y축은 오류 비율(%). 삽입(Insertion), 삭제(Deletion), 교체(Substitution) 오류 유형을 분리하여 WER, WER LM, Oracle WER과 함께 표시합니다.</li>
<li><strong>핵심 메시지:</strong> 짧은 발화(2단어 이하)에서는 <strong>삽입·교체 오류</strong>가 주된 문제이고, 긴 발화(10단어 이상)에서는 <strong>삭제 오류</strong>가 지배적입니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>짧은 발화에서의 오류는 &quot;단어를 쪼개서 두 개로 인식하는&quot; 문제에서 비롯됩니다. 긴 발화에서의 삭제 오류는 &quot;훈련 데이터에 긴 발화가 적어 어텐션이 길을 잃는&quot; 문제입니다. 이 그림 하나로 LAS가 어디에서 왜 실패하는지 명확하게 이해할 수 있습니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 LAS가 복잡한 기존 시스템 없이도 충분한 성능을 내는지 검증하기 위해 구글의 대규모 데이터셋으로 실험을 설계했습니다.</p>
<table>
<thead>
<tr>
<th>실험 항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>구글 음성 검색 약 300만 발화 (약 2,000시간), 데이터 증강으로 <strong>20배 확장</strong></td>
</tr>
<tr>
<td><strong>음향 특징</strong></td>
<td>40차원 log-mel 필터뱅크, 10ms 간격 추출</td>
</tr>
<tr>
<td><strong>모델 구조</strong></td>
<td>하단 BLSTM + pBLSTM 3층(각 512노드, 256/방향) + 스펠러 2층 LSTM(512노드)</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>WER(단어 오류율) — 대체·삽입·삭제 오류 단어 비율</td>
</tr>
<tr>
<td><strong>비교 대상</strong></td>
<td>당시 SOTA인 CLDNN-HMM 시스템(WER 8.0%)</td>
</tr>
</tbody></table>
<h3 id="결과-요약-table-1-기준">결과 요약 (Table 1 기준)</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>Clean WER</th>
<th>Noisy WER</th>
</tr>
</thead>
<tbody><tr>
<td><strong>CLDNN-HMM (SOTA)</strong></td>
<td><strong>8.0%</strong></td>
<td><strong>8.9%</strong></td>
</tr>
<tr>
<td>LAS (기본)</td>
<td>16.2%</td>
<td>19.0%</td>
</tr>
<tr>
<td>LAS + LM Rescoring</td>
<td>12.6%</td>
<td>14.7%</td>
</tr>
<tr>
<td>LAS + Sampling</td>
<td>14.1%</td>
<td>16.5%</td>
</tr>
<tr>
<td><strong>LAS + Sampling + LM Rescoring</strong></td>
<td><strong>10.3%</strong></td>
<td><strong>12.0%</strong> ✅</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>발음 사전도, HMM도, 외부 언어 모델도 없는 순수 LAS가 WER 14.1%를 달성했습니다. 언어 모델 재채점만 추가하면 10.3%로, 당시 SOTA(8.0%)와의 격차가 <strong>2.3%p</strong> 수준까지 좁혀졌습니다. 모든 복잡성을 제거했음에도 상용화 수준에 근접한 성능을 낸 것입니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>HMM 파이프라인 완전 제거</strong> — 발음 사전, HMM, 별도 훈련 과정이 모두 사라졌습니다.</li>
<li><strong>OOV 문제 자동 해결</strong> — 문자 단위로 출력하므로 사전에 없는 단어도 조합해서 표현할 수 있습니다.</li>
<li><strong>암묵적 언어 모델 내재화</strong> — 조건부 독립 가정 없이 이전 문자를 참조해 다음 문자를 예측합니다.</li>
<li><strong>다양한 철자 표현 가능</strong> — 빔 서치 결과에 &quot;triple a&quot;와 &quot;aaa&quot;가 동시에 생성되는 것처럼, CTC로는 불가능한 다양한 표현을 자연스럽게 만들어냅니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>실시간 처리 불가(Offline 모델)</strong> — pBLSTM이 양방향 구조이므로 발화가 끝날 때까지 기다려야 합니다. 유튜브 자동 자막처럼 말하는 도중 텍스트가 찍히는 서비스에 바로 쓸 수 없습니다.</li>
<li><strong>천문학적 데이터 요구량</strong> — 2,000시간 데이터 + 20배 증강 없이는 모델이 제대로 수렴하지 않습니다. 데이터가 적은 언어나 도메인에서는 적용이 어렵습니다.</li>
<li><strong>긴 발화에서 어텐션 실패</strong> — 훈련 데이터 분포보다 긴 발화가 들어오면 삭제 오류가 급증합니다.</li>
<li><strong>결국 외부 언어 모델 필요</strong> — &quot;Fully End-to-End&quot;를 강조하지만 최상위 성능(10.3%)은 외부 n-gram 언어 모델 재채점이 더해진 결과입니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<p>저자들이 논문에서 직접 제안하거나 이후 연구로 이어진 3가지 방향입니다.</p>
<ol>
<li><strong>온라인 스트리밍 적용</strong> — pBLSTM을 단방향 구조로 바꾸고 Monotonic Attention을 결합해 실시간 처리를 가능하게 만듭니다. (이후 MoChA, RNN-T 연구로 발전)</li>
<li><strong>다국어 범용 모델</strong> — 유니코드 서브워드를 출력으로 확장하고 언어 ID 태그를 붙여 수십 개 언어를 하나의 LAS로 처리합니다.</li>
<li><strong>비지도 사전학습 결합</strong> — wav2vec 2.0처럼 정답 없는 오디오만으로 리스너를 먼저 학습시킨 뒤 LAS로 파인튜닝하면, 적은 데이터로도 높은 성능을 낼 수 있습니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>&quot;모델에 더 많은 정보(발음 사전, HMM 상태)를 줄수록 더 잘 배울 것이다&quot;라고 생각했습니다.</p>
<blockquote>
<p>하지만 LAS는 오히려 <strong>정보를 덜 줬더니 더 잘 배웠습니다.</strong> 발음 사전을 주입하는 사전학습을 시도했지만 오히려 성능이 올라가지 않았다고 논문이 직접 밝힙니다. 좋은 학습 설계란 &#39;더 많은 규칙을 주입하는 것&#39;이 아니라 &#39;올바른 구조와 자유를 주는 것&#39;임을 배웠습니다.</p>
</blockquote>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>피라미드 구조(pBLSTM)가 단순히 &quot;연산량 줄이기&quot;로만 보였습니다. 하지만 논문은 이것이 없으면 <strong>한 달을 학습해도 수렴하지 않는다</strong>는 극단적 사실을 실험으로 증명했습니다. 구조적 설계 하나가 학습 가능성 자체를 결정한다는 점이 강렬하게 남았습니다.</p>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>스마트 홈 기기처럼 메모리가 제한된 온디바이스 환경에서 LAS를 경량화하려면 pBLSTM을 단방향 피라미드 LSTM으로 교체하고, 어텐션을 Local Window 방식으로 제한하면 실시간 음성 인식이 가능한 구조가 만들어질 것 같습니다. 2,000시간이 아닌 적은 데이터로도 작동하게 하려면 wav2vec 같은 자기지도 사전학습과 결합하는 방향이 현실적으로 보입니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>전통적 음성 인식은 파이프라인이 파편화되어 전체 최적화가 불가능하고, CTC는 조건부 독립 가정이 치명적 약점</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>pBLSTM으로 오디오를 8배 압축 + 어텐션으로 문자별 집중 구간 학습 = 단일 Seq2Seq 종단간 모델</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>발음 사전·HMM 없이 WER 14.1%, LM 재채점 추가 시 10.3% — SOTA(8.0%)와 2.3%p 차이</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>pBLSTM 없이 한 달 학습해도 수렴하지 못한다는 실험 결과 — 구조적 설계가 학습 가능성 자체를 결정함</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>양방향 pBLSTM으로 인한 실시간 처리 불가, 최상위 성능에는 결국 외부 언어 모델이 필요</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>단방향 경량화 + Monotonic Attention으로 온디바이스 실시간 처리, wav2vec 결합으로 저자원 언어 대응</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>LAS는 피라미드형 압축(Listen)과 집중 메커니즘(Attend)으로 수천 프레임의 오디오를 다루는 장벽을 넘어, 발음 사전도 HMM도 없이 오디오를 문자로 직접 받아쓰는 End-to-End 음성 인식 시대를 연 혁명적 아키텍처다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Connectionist Temporal Classification (CTC)]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Connectionist-Temporal-Classification-CTC</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Connectionist-Temporal-Classification-CTC</guid>
            <pubDate>Wed, 04 Mar 2026 13:39:56 GMT</pubDate>
            <description><![CDATA[<h3 id="connectionist-temporal-classification-ctc-httpswwwcstorontoedugravesicml_2006pdf">Connectionist Temporal Classification (CTC) (<a href="https://www.cs.toronto.edu/~graves/icml_2006.pdf">https://www.cs.toronto.edu/~graves/icml_2006.pdf</a>)</h3>
<h4 id="정답의-시간표-없이-스스로-학습하는-음성-인식의-혁명">정답의 시간표 없이 스스로 학습하는 음성 인식의 혁명</h4>
<blockquote>
<p>&quot;안녕&quot;을 0.5초에 말하든 2초에 말하든, <strong>사람이 시간 짝을 맞춰주지 않아도</strong> 인공지능이 스스로 패턴을 찾아내는 수학적 마법.<br>ICML 2006 | Alex Graves et al. (IDSIA, Switzerland / TU München)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 음성 인식 AI가 <strong>&#39;생각보다 훨씬 많은 사전 준비를 요구해왔다&#39;</strong> 는 불편한 진실을 파고든 연구입니다.</p>
<p>기존 인공지능은 순서가 있는 데이터를 다룰 수 있습니다. 하지만 치명적인 단점이 있었습니다. 입력 데이터와 정답의 짝이 <strong>시간별로 정확히 맞아야</strong> 했습니다. 현실의 음성은 소리의 시작과 끝이 명확히 나뉘지 않습니다. 사람이 일일이 시간 짝을 맞추는 작업은 돈과 시간이 너무 많이 듭니다.</p>
<p>이 논문은 미리 짝을 맞추지 않고도 인공지능이 스스로 정답을 찾아내는 방법인 <strong>CTC(Connectionist Temporal Classification)</strong> 를 제안합니다. 이 글을 끝까지 읽으시면, 복잡한 수식에 빠지지 않고도 왜 이 논문이 현재 음성 인식 AI의 근본 공식이 되었는지 직관적으로 깨닫게 되실 겁니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이런 연구가 필요했는지 배경지식을 가볍게 짚고 넘어가 봅시다.</p>
<h3 id="기존-음성-인식의-지배자-hmm">기존 음성 인식의 지배자: HMM</h3>
<p>2006년 이전의 음성 인식은 <strong>은닉 마르코프 모델(HMM, Hidden Markov Model)</strong> 이 지배했습니다. 하지만 HMM에는 구조적인 한계가 세 가지 있었습니다.</p>
<table>
<thead>
<tr>
<th>한계</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>task-specific 지식 필요</strong></td>
<td>상태 모델 설계 등 사람이 직접 설계해야 하는 부분이 많음</td>
</tr>
<tr>
<td><strong>독립성 가정</strong></td>
<td>바로 직전 상태만 보고 다음을 예측 — 긴 문맥 기억 불가</td>
</tr>
<tr>
<td><strong>생성 방식 학습</strong></td>
<td>분류 문제임에도 불구하고 생성 모델 방식으로 훈련함</td>
</tr>
</tbody></table>
<h3 id="순환-신경망rnn의-가능성과-한계">순환 신경망(RNN)의 가능성과 한계</h3>
<p>RNN은 시계열 데이터에 강하고, 사전 지식 없이 훈련이 가능한 이점이 있었습니다. 하지만 한 가지 결정적인 문제가 있었습니다.</p>
<blockquote>
<p>기존 RNN은 매 순간마다 <strong>독립적인 글자 분류</strong>만 할 수 있었습니다. 훈련하려면 소리 데이터의 어느 타이밍에 어느 글자가 나오는지, 사람이 수작업으로 만든 <strong>완벽한 시간표(정답 라벨)</strong> 가 꼭 필요했습니다.</p>
</blockquote>
<h3 id="해결해야-할-근본-문제">해결해야 할 근본 문제</h3>
<p>사람마다 말하는 속도가 다릅니다. 어떤 사람은 &quot;안녕&quot;을 0.5초에, 다른 사람은 2초에 말합니다. 이 길이를 매번 수작업으로 기록하는 것은 불가능합니다. 이 문제를 풀지 못하면 음성 인식 AI를 실생활에 널리 쓸 수 없습니다.</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;기존 방법은 너무 많은 사전 작업을 요구하고, 모델의 잠재력을 제대로 쓰지 못한다&quot;</strong> 는 것입니다.</p>
<h3 id="기존-방식의-한계">기존 방식의 한계</h3>
<table>
<thead>
<tr>
<th>방식</th>
<th>설명</th>
<th>치명적 단점</th>
</tr>
</thead>
<tbody><tr>
<td><strong>HMM</strong></td>
<td>통계 기반으로 시퀀스를 모델링</td>
<td>먼 과거 문맥을 기억하지 못함</td>
</tr>
<tr>
<td><strong>HMM-RNN 하이브리드</strong></td>
<td>HMM이 분절을 담당, RNN이 분류</td>
<td>사람이 만든 시간표 필수, HMM의 단점을 그대로 상속</td>
</tr>
<tr>
<td><strong>프레임 단위 모델</strong></td>
<td>소리를 짧은 조각으로 나눠 각각 분류</td>
<td>매 조각마다 정답 요구 — 수작업 필수</td>
</tr>
</tbody></table>
<h3 id="직관적-비유-🏃">직관적 비유 🏃</h3>
<p>음성 인식을 음악 받아쓰기로 비유해 봅시다.</p>
<ul>
<li><strong>기존 방식:</strong> 악보에 &#39;2박자 자리에는 반드시 &#39;도&#39;를 쳐야 해!&#39;라고 미리 표시된 악보(시간표)가 있어야만 연습할 수 있습니다.</li>
<li><strong>CTC가 풀려는 것:</strong> 악보 없이 그냥 음악을 들려주고, 인공지능이 스스로 &quot;이 부분이 &#39;도&#39;겠구나&quot;를 터득하게 만드는 것입니다.</li>
</ul>
<blockquote>
<p><strong>이 문제를 해결하면</strong><br>수작업 시간표(Forced Alignment) 없이 음성-텍스트 쌍 데이터만 있으면 처음부터 끝까지 신경망 하나로(End-to-End) 학습이 가능해집니다.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>CTC는 <strong>&#39;빈칸(Blank) 기호 도입&#39;과 &#39;모든 경로 합산&#39;</strong> 이라는 두 가지 핵심 아이디어로 이 문제를 해결합니다.</p>
<h3 id="전체-작동-순서">전체 작동 순서</h3>
<ol>
<li><strong>빈칸 기호 추가</strong> — 알파벳 외에 &#39;아무 글자도 아님(blank)&#39;을 뜻하는 기호를 새로 만듭니다.</li>
<li><strong>매 순간 확률 계산</strong> — 인공지능이 매 타임스텝마다 각 글자(또는 빈칸)가 나올 확률을 계산합니다.</li>
<li><strong>중복 합치기</strong> — 연속으로 같은 글자가 나오면 하나로 압축합니다.</li>
<li><strong>빈칸 제거</strong> — 남은 빈칸을 모두 지우면 최종 단어가 완성됩니다.</li>
</ol>
<h3 id="빈칸blank-기호의-역할">빈칸(Blank) 기호의 역할</h3>
<p>빈칸 기호는 단순히 &#39;아무것도 없음&#39;이 아닙니다. 중요한 역할이 있습니다.</p>
<blockquote>
<p><strong>예시:</strong> &#39;Hello&#39;의 &#39;l&#39;은 연속으로 두 번 등장합니다. 빈칸 없이 [H, e, l, l, o]가 나오면 인공지능은 중복 압축 규칙에 의해 &#39;Helo&#39;로 오해합니다. 빈칸이 있어야 [H, e, l, <strong>blank</strong>, l, o] → &#39;Hello&#39;가 유지됩니다.</p>
</blockquote>
<h3 id="직관적-예시-4가지-💡">직관적 예시 4가지 💡</h3>
<table>
<thead>
<tr>
<th>상황</th>
<th>인공지능 예측</th>
<th>최종 결과</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;안<del>~</del>녕&quot;이라고 길게 말함</td>
<td>[안, 안, blank, 녕]</td>
<td><strong>안녕</strong></td>
</tr>
<tr>
<td>&quot;Hello&quot;에서 l이 두 번 나옴</td>
<td>[H, e, l, blank, l, o]</td>
<td><strong>Hello</strong></td>
</tr>
<tr>
<td>태블릿에 &#39;a&#39;를 천천히 씀</td>
<td>[a, a, a, a, a, a, a, a]</td>
<td><strong>a</strong></td>
</tr>
<tr>
<td>&quot;나...는&quot;이라고 더듬으며 말함</td>
<td>[나, blank, blank, blank, 는]</td>
<td><strong>나는</strong></td>
</tr>
</tbody></table>
<hr>
<h3 id="수식-이해하기">수식 이해하기</h3>
<h4 id="첫-번째-수식-하나의-경로길를-통과할-확률">첫 번째 수식: 하나의 경로(길)를 통과할 확률</h4>
<p><strong>비유 먼저:</strong><br>동전을 3번 던집니다. &#39;앞-뒤-앞&#39;이 나올 확률은 어떻게 구할까요? 각 시도의 확률을 모두 <strong>곱</strong>하면 됩니다. CTC도 똑같습니다.</p>
<p>$$p(\pi | x) = \prod_{t=1}^{T} y_{\pi_t}^t$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$x$</td>
<td>입력된 소리 데이터</td>
</tr>
<tr>
<td>$\pi$</td>
<td>특정한 글자의 순서 (예: a-blank-b)</td>
</tr>
<tr>
<td>$y_{\pi_t}^t$</td>
<td>인공지능이 시간 $t$에 그 글자를 예측할 확률</td>
</tr>
<tr>
<td>$\prod$</td>
<td>전부 곱하라는 수학 기호</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>이 수식이 없다면?</strong> 인공지능이 예측한 수많은 글자 조합 중 어떤 조합이 더 믿을 만한지 점수를 매길 수 없습니다.</p>
</blockquote>
<hr>
<h4 id="두-번째-수식-모든-가능한-길을-합쳐서-정답에-도달할-확률">두 번째 수식: 모든 가능한 길을 합쳐서 정답에 도달할 확률</h4>
<p><strong>비유 먼저:</strong><br>서울에서 부산까지 가는 길은 여러 개입니다. &#39;부산에 도착할 전체 확률&#39;은 고속도로 확률 + 국도 확률을 모두 <strong>더하면</strong> 됩니다. &#39;cat&#39;이라는 정답을 만드는 경로는 수백 개가 넘습니다. 이를 전부 더하면 &#39;cat&#39;이 정답일 최종 확률이 나옵니다.</p>
<p>$$p(l | x) = \sum_{\pi \in \mathcal{B}^{-1}(l)} p(\pi | x)$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$l$</td>
<td>최종 정답 텍스트 (예: cat)</td>
</tr>
<tr>
<td>$\mathcal{B}^{-1}(l)$</td>
<td>압축했을 때 &#39;cat&#39;이 될 수 있는 <strong>모든 경로들의 모음</strong></td>
</tr>
<tr>
<td>$\sum$</td>
<td>전부 더하라는 수학 기호</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>이 수식이 없다면?</strong> 인공지능은 정답이 되는 &#39;모든 경우의 수&#39;를 고려하지 못해 학습 자체가 불가능해집니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-1--framewise-vs-ctc-출력-비교">📊 Figure 1 — Framewise vs CTC 출력 비교</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/b814505c-6944-4411-885e-0cd4e370f55a/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 같은 음성 신호(&quot;the sound of&quot;)를 Framewise 모델과 CTC 모델이 각각 어떻게 처리하는지 비교한 출력 활성화 그래프. 가로축은 시간, 세로축은 각 음소(phoneme)의 예측 확률입니다.</li>
<li><strong>핵심 메시지:</strong> Framewise는 사람이 표시한 세로 구분선(수동 분절)에 맞춰 억지로 글자를 출력하려다 경계를 조금만 틀려도 오류가 납니다. 반면 CTC는 확신이 생기는 순간에만 <strong>날카로운 스파이크(spike)</strong> 를 뱉고, 나머지는 깔끔하게 blank로 채웁니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>CTC 출력 그래프를 보면 &#39;dcl&#39;과 &#39;d&#39;처럼 항상 붙어 다니는 음소들이 <strong>이중 스파이크(double spike)</strong> 로 묶여서 예측됩니다. AI가 스스로 &quot;얘네는 세트야&quot;라는 언어적 패턴을 수작업 없이 학습했다는 증거입니다. Framewise 결과를 쓰려면 후처리가 필요하지만, CTC 결과는 스파이크만 읽으면 바로 정답이 됩니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2--prefix-search-decoding-트리">📊 Figure 2 — Prefix Search Decoding 트리</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/49596d39-afa4-4c14-b4e6-18611e41c06f/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 알파벳 X, Y로 구성된 라벨 공간에서 가장 확률 높은 정답을 찾아가는 트리 탐색 과정. 각 노드 위의 숫자는 해당 접두어(prefix)로 시작하는 모든 정답의 총 확률입니다.</li>
<li><strong>핵심 메시지:</strong> 가장 확률 높은 prefix를 우선적으로 확장해 나가다가, 단일 정답 &#39;XY&#39;가 나머지 모든 prefix보다 확률이 높아지는 순간 탐색을 멈춥니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>이 방식은 &#39;최선의 경로 하나만 보기(Best Path Decoding)&#39;보다 항상 더 정확한 정답을 찾아냅니다. 단, CTC 출력이 충분히 뾰족하게(peaked) 학습되어야 탐색 시간이 폭발하지 않습니다. 논문에서 blank 확률 99.99% 이상인 지점을 경계로 나눠 각 구간을 독립적으로 탐색하는 휴리스틱을 추가한 이유가 여기 있습니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-3--forward-backward-알고리즘-cat-예시">📊 Figure 3 — Forward-Backward 알고리즘: &#39;CAT&#39; 예시</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/857345a7-16c2-4e08-8206-9a319fc36726/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 정답 &#39;CAT&#39;을 학습할 때, 가능한 모든 경로의 확률을 효율적으로 계산하는 동적 프로그래밍 다이어그램. 검은 원은 실제 글자(C, A, T), 흰 원은 blank를 나타냅니다. 화살표는 허용된 전이(transition) 방향을 표시합니다.</li>
<li><strong>핵심 메시지:</strong> 앞에서 뒤로(Forward) 변수와 뒤에서 앞으로(Backward) 변수를 재귀적으로 계산합니다. 오른쪽 상단의 연결되지 않은 흰 원들은 &quot;남은 시간이 부족해 도달할 수 없는 경로&quot;를 나타냅니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>수백 개가 넘는 경로를 하나씩 다 계산하면 컴퓨터가 죽습니다. Forward-Backward 알고리즘은 이 계산을 HMM에서 쓰던 방식과 유사하게 재귀식으로 분해해서, 결국 <strong>선형 시간(Linear Time)</strong> 만에 풀어냅니다. 이 알고리즘적 우아함이 CTC를 실용적으로 만든 핵심입니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-4--ctc-오차-신호의-학습-단계별-진화">📊 Figure 4 — CTC 오차 신호의 학습 단계별 진화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/5cbcfbf5-6dcb-4298-af10-c28f43fa137f/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 동일한 음성 시퀀스에 대해 학습 단계별 출력 활성화(왼쪽 열)와 그에 대응하는 오차 신호(오른쪽 열)를 3단계 (a), (b), (c)로 비교한 그래프. 점선은 blank 유닛의 확률을 나타냅니다.</li>
<li><strong>핵심 메시지:</strong> (a) 초기에는 랜덤 가중치로 오차가 정답 라벨에만 의존합니다. (b) 학습이 진행되면 예측 주변으로 오차가 집중되기 시작합니다. (c) 충분히 학습된 뒤에는 올바른 글자를 강하게 확신하며 오차가 거의 사라집니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>(c) 단계에서 오차 신호가 거의 사라진다는 것은 &quot;모델이 이미 정답을 확신하고 있어서 더 고칠 게 없다&quot;는 뜻입니다. 학습 초반에 헤매다가 패턴을 깨닫는 순간 성적이 수직 상승하는 이유가 이 그림에 고스란히 담겨 있습니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 새로운 방법(CTC)이 기존 방법보다 성능이 뛰어난지 확인하기 위해 치밀한 실험을 설계했습니다.</p>
<table>
<thead>
<tr>
<th>실험 항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>데이터셋</strong></td>
<td>TIMIT (영어 음성 코퍼스 — 4,620개 훈련 / 1,680개 테스트 발화)</td>
</tr>
<tr>
<td><strong>음소 분류 수</strong></td>
<td>61개 음소 + blank 1개 = <strong>총 62개 출력</strong></td>
</tr>
<tr>
<td><strong>신경망 구조</strong></td>
<td>BLSTM (양방향 Long Short-Term Memory, 파라미터 114,662개)</td>
</tr>
<tr>
<td><strong>평가 지표</strong></td>
<td>LER (Label Error Rate) — 정답과 비교해서 삽입/삭제/교체된 글자 비율</td>
</tr>
</tbody></table>
<h3 id="결과-요약-table-1-기준">결과 요약 (Table 1 기준)</h3>
<table>
<thead>
<tr>
<th>시스템</th>
<th>LER (낮을수록 우수)</th>
</tr>
</thead>
<tbody><tr>
<td>Context-independent HMM</td>
<td>38.85%</td>
</tr>
<tr>
<td>Context-dependent HMM</td>
<td>35.21%</td>
</tr>
<tr>
<td>BLSTM/HMM (Hybrid)</td>
<td>33.84%</td>
</tr>
<tr>
<td>Weighted error BLSTM/HMM</td>
<td>31.57%</td>
</tr>
<tr>
<td><strong>CTC (Best Path)</strong></td>
<td><strong>31.47%</strong></td>
</tr>
<tr>
<td><strong>CTC (Prefix Search)</strong></td>
<td><strong>30.51%</strong> ✅</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>결과 해석</strong><br>CTC(Prefix Search)는 사전 분절 작업이 전혀 없었음에도 불구하고, 가장 복잡한 Hybrid 시스템을 누르고 <strong>최저 오답률 30.51%</strong> 로 1위를 달성했습니다. 하이브리드 시스템은 가중치 오차 보정(heuristics)을 써야 겨우 비슷해졌지만, CTC는 그런 꼼수 없이 순수하게 이겼습니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>노동 해방</strong> — 사람이 직접 데이터를 분절하던 고된 사전 작업을 완전히 없앴습니다.</li>
<li><strong>End-to-End 학습</strong> — 소리 → 글자 변환 전 과정을 단일 신경망 하나로 처리합니다.</li>
<li><strong>새로운 시대 개막</strong> — 소리, 영상, 필기 등 연속 데이터를 다루는 모든 AI 연구의 기본 공식이 되었습니다.</li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>문법 지식 부족 (독립성 가정)</strong> — 매 타임스텝의 출력이 서로 독립적으로 계산됩니다. &#39;가&#39; 다음에 &#39;나&#39;가 올 확률이 높다는 언어적 문맥을 깊게 학습하지 못합니다. 별도의 언어 모델(Language Model)이 꼭 필요합니다.</li>
<li><strong>너무 뾰족한 예측</strong> — 글자를 뱉을 때 100% 확신하고 나머지는 모두 blank로 확신하는 극단적 패턴이 생깁니다. 다른 모듈과 조합할 때 조화롭게 어울리기 어렵습니다.</li>
<li><strong>실시간 처리의 한계</strong> — 논문의 BLSTM 구조는 미래 문맥까지 보는 <strong>양방향(Bidirectional)</strong> 구조입니다. 발화가 끝날 때까지 기다려야 해서 유튜브 자동 자막처럼 즉각 반응하는 실시간 서비스에는 당장 적용이 어렵습니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<p>저자들이 논문에서 직접 제안한 3가지 방향입니다.</p>
<ol>
<li><strong>Attention 모델과 결합</strong> — 소리 타이밍은 CTC가, 문장의 매끄러움은 Attention이 담당하도록 역할을 나눕니다.</li>
<li><strong>단어 단위 학습</strong> — 알파벳 하나씩 예측하지 말고 &#39;Apple&#39;, &#39;Banana&#39; 같은 단어 자체를 예측하게 만들어 오타를 줄입니다.</li>
<li><strong>단방향 구조로 개조</strong> — 미래의 소리를 보지 않는 단방향(Unidirectional) 구조로 바꾸면, 정확도를 조금 희생하는 대신 스마트폰 음성 비서처럼 즉시 대답하는 서비스가 가능해집니다.</li>
</ol>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>AI 연구에서 <strong>&#39;빈칸(blank)&#39;이라는 단 하나의 기호를 추가하는 것</strong>이 얼마나 혁명적인 변화를 가져오는지 깨달았습니다. 수학적으로 풀리지 않던 길이 불일치(Misalignment) 문제가, 빈칸 기호 하나로 인해 경우의 수를 합산할 수 있는 구조로 바뀌었습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>&quot;인공지능에게 더 많은 정보(시간표)를 줄수록 더 잘 배울 것이다&quot;라고 생각했습니다.</p>
<blockquote>
<p>하지만 CTC는 오히려 <strong>정보를 덜 줬더니(시간표 없이) 더 잘 배웠습니다.</strong> 제약을 없애자 모델이 스스로 최적의 패턴을 찾아낸 것입니다. 좋은 학습 설계란 &#39;더 많은 정보를 주는 것&#39;이 아니라 &#39;올바른 자유를 주는 것&#39;임을 배웠습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>이 기법은 음성 인식을 넘어 <strong>필기 인식, 영상 자막, 단백질 서열 분석</strong>처럼 입력과 출력의 길이가 다를 수 있는 모든 분야에 직접 적용 가능합니다. 온디바이스 AI에서 경량 음성 인식 모델을 설계할 때, CTC를 기반으로 단방향 구조와 결합하면 실시간성과 정확도를 동시에 잡는 아키텍처를 설계해볼 수 있겠다고 생각했습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>기존 RNN은 훈련하려면 사람이 직접 만든 시간별 정답 라벨(Forced Alignment)이 꼭 필요했음</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>blank 기호 도입 + 정답이 되는 모든 경로의 확률을 합산하는 CTC Loss로 사전 분절 없이 학습</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>TIMIT 데이터셋에서 HMM 및 HMM-RNN 하이브리드를 꺾고 LER 30.51%로 SOTA 달성</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>미분 불가능했던 &#39;경로 선택&#39; 문제를 Forward-Backward 동적 프로그래밍으로 우회한 수학적 우아함</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>매 타임스텝 독립 예측 가정으로 인해 언어 문맥 모델링이 약하고, 양방향 구조 탓에 실시간 처리가 어려움</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>Attention 모델과의 결합(CTC+Attention), 단방향 경량화를 통한 온디바이스 실시간 음성 인식</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>CTC는 &#39;blank&#39;라는 기호 하나와 Forward-Backward 알고리즘으로, 사람이 만든 시간표 없이도 인공지능이 스스로 소리와 글자의 관계를 배울 수 있게 만든 End-to-End 음성 인식의 혁명적 기초다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Layer-wise Relevance Propagation (LRP) vs Backpropagation]]></title>
            <link>https://velog.io/@dev_brojean/Layer-wise-Relevance-Propagation-LRP-vs-Backpropagation</link>
            <guid>https://velog.io/@dev_brojean/Layer-wise-Relevance-Propagation-LRP-vs-Backpropagation</guid>
            <pubDate>Tue, 03 Mar 2026 13:16:05 GMT</pubDate>
            <description><![CDATA[<h3 id="-둘-다-역방향인데-뭐가-다를까">― 둘 다 “역방향”인데 뭐가 다를까?</h3>
<p>논문 리뷰(<a href="https://aclanthology.org/P19-1580.pdf)%EB%A5%BC">https://aclanthology.org/P19-1580.pdf)를</a> 하며, LRP와 BackPropagation의 차이가 뭔지 너무 궁금하여 작성하게되었다.</p>
<blockquote>
<p>LRP도 뒤로 전파하고, Backpropagation도 뒤로 전파하는데
도대체 뭐가 다른 걸까?</p>
</blockquote>
<p>결론부터 말하면,</p>
<ul>
<li><strong>Backpropagation</strong>은 <em>학습을 위한 알고리즘</em></li>
<li><strong>LRP (Layer-wise Relevance Propagation)</strong>는 <em>설명을 위한 알고리즘</em></li>
</ul>
<p>같은 &quot;역방향 계산&quot;처럼 보이지만, <strong>목적과 수학적 의미가 완전히 다르다.</strong></p>
<hr>
<h1 id="1-backpropagation-학습을-위한-역전파">1. Backpropagation: 학습을 위한 역전파</h1>
<h2 id="1-1-목적">1-1. 목적</h2>
<p>Backpropagation의 목적은 단 하나다.</p>
<blockquote>
<p>&quot;가중치를 얼마나 바꿔야 손실이 줄어드는가?&quot;</p>
</blockquote>
<p>즉, <strong>최적화(optimization)</strong>를 위한 알고리즘이다.</p>
<hr>
<h2 id="1-2-무엇을-계산하는가">1-2. 무엇을 계산하는가?</h2>
<p>Backpropagation은 다음을 계산한다.</p>
<p>[
\frac{\partial L}{\partial w}
]</p>
<ul>
<li>(L): 손실 함수</li>
<li>(w): 가중치</li>
</ul>
<p>이 값은 <strong>기울기(gradient)</strong>이며,
의미는 다음과 같다.</p>
<blockquote>
<p>&quot;이 가중치를 아주 조금 바꾸면, 손실이 얼마나 변하는가?&quot;</p>
</blockquote>
<p>즉, <strong>민감도(sensitivity)</strong>를 구하는 것이다.</p>
<hr>
<h2 id="1-3-직관적인-예시">1-3. 직관적인 예시</h2>
<p>출력이 다음과 같다고 해보자.</p>
<p>[
y = x_1 w_1 + x_2 w_2
]</p>
<p>Backpropagation은 다음을 계산한다.</p>
<p>[
\frac{\partial y}{\partial x_1} = w_1
]</p>
<p>이는 말 그대로:</p>
<blockquote>
<p>&quot;x₁을 조금 바꾸면 출력이 얼마나 변하는가?&quot;</p>
</blockquote>
<p>현재 x₁이 실제로 얼마나 기여했는지는 직접적으로 보지 않는다.
오직 <strong>변화율</strong>만 본다.</p>
<hr>
<h1 id="2-lrp-설명을-위한-역전파">2. LRP: 설명을 위한 역전파</h1>
<h2 id="2-1-목적">2-1. 목적</h2>
<p>LRP의 목적은 전혀 다르다.</p>
<blockquote>
<p>&quot;이 예측이 나오는데, 각 뉴런이 얼마나 기여했는가?&quot;</p>
</blockquote>
<p>즉, <strong>설명(Explainability)</strong>을 위한 알고리즘이다.</p>
<hr>
<h2 id="2-2-핵심-개념-relevance-기여도">2-2. 핵심 개념: Relevance (기여도)</h2>
<p>LRP는 출력에서 시작한다.</p>
<p>예를 들어 어떤 클래스의 점수가 10이라면,
그 10이라는 값을 아래 층으로 <strong>분배</strong>해 내려간다.</p>
<p>그리고 이 분배는 다음 성질을 유지한다.</p>
<p>[
\sum R^{(l+1)} = \sum R^{(l)}
]</p>
<p>즉,</p>
<blockquote>
<p>Relevance의 총합은 항상 보존된다.</p>
</blockquote>
<p>이를 <strong>Conservation Property(보존 성질)</strong>라고 한다.</p>
<hr>
<h2 id="2-3-기본-분배-방식-직관적-형태">2-3. 기본 분배 방식 (직관적 형태)</h2>
<p>LRP의 기본 아이디어는 다음과 같다.</p>
<p>[
R_i = \sum_j \frac{a_i w_{ij}}{\sum_k a_k w_{kj}} R_j
]</p>
<p>여기서:</p>
<ul>
<li>(a_i): 뉴런 활성값</li>
<li>(w_{ij}): 가중치</li>
<li>(R_j): 상위층 relevance</li>
</ul>
<p>의미는 단순하다.</p>
<blockquote>
<p>출력에 기여한 비율만큼 relevance를 나눠준다.</p>
</blockquote>
<p>즉, 실제 계산된 출력의 <strong>구성비</strong>를 따라 기여도를 분해하는 방식이다.</p>
<hr>
<h1 id="3-핵심-차이-민감도-vs-기여도">3. 핵심 차이: 민감도 vs 기여도</h1>
<table>
<thead>
<tr>
<th>구분</th>
<th>Backpropagation</th>
<th>LRP</th>
</tr>
</thead>
<tbody><tr>
<td>목적</td>
<td>학습</td>
<td>설명</td>
</tr>
<tr>
<td>계산 대상</td>
<td>Gradient</td>
<td>Relevance</td>
</tr>
<tr>
<td>의미</td>
<td>변화율(민감도)</td>
<td>공로(기여도)</td>
</tr>
<tr>
<td>총합 보존</td>
<td>없음</td>
<td>있음</td>
</tr>
</tbody></table>
<hr>
<h2 id="3-1-왜-gradient-≠-기여도인가">3-1. 왜 Gradient ≠ 기여도인가?</h2>
<p>Gradient가 크다는 것은</p>
<blockquote>
<p>&quot;조금 바꾸면 결과가 크게 변한다&quot;</p>
</blockquote>
<p>는 뜻이다.</p>
<p>하지만 이것은</p>
<blockquote>
<p>&quot;현재 결과를 많이 만들었다&quot;</p>
</blockquote>
<p>는 뜻이 아니다.</p>
<p>예를 들어:</p>
<ul>
<li>어떤 뉴런은 지금 출력에 거의 쓰이지 않았지만</li>
<li>만약 값을 바꾸면 출력이 크게 바뀔 수도 있다</li>
</ul>
<p>이 경우 gradient는 크지만 실제 기여는 작다.</p>
<hr>
<h1 id="4-lrp의-다양한-rule">4. LRP의 다양한 Rule</h1>
<p>실제 신경망에서는 0으로 나누는 문제, 음수 기여, 불안정성 문제가 발생한다.
그래서 LRP는 여러 분배 규칙을 사용한다.</p>
<h2 id="4-1-ε-rule-안정성-확보">4-1. ε-rule (안정성 확보)</h2>
<p>[
\frac{a_i w_{ij}}{\sum_k a_k w_{kj} + \epsilon}
]</p>
<p>작은 ε를 더해 분모가 0에 가까워지는 것을 방지한다.</p>
<hr>
<h2 id="4-2-γ-rule-양의-증거-강조">4-2. γ-rule (양의 증거 강조)</h2>
<p>양수 기여를 더 강조하도록 가중치를 조정한다.</p>
<p>분류 문제에서 “이 클래스를 지지한 증거”를 더 잘 드러내는 효과가 있다.</p>
<hr>
<h1 id="5-transformer-관점에서-보면">5. Transformer 관점에서 보면</h1>
<p>예를 들어,</p>
<ul>
<li>어떤 토큰이 최종 예측에 중요했는지 알고 싶다면?</li>
</ul>
<h3 id="backpropagation">Backpropagation</h3>
<ul>
<li>그 토큰 embedding의 gradient를 확인</li>
<li>의미: &quot;조금 바꾸면 결과가 얼마나 변할까?&quot;</li>
</ul>
<h3 id="lrp">LRP</h3>
<ul>
<li>그 토큰에 relevance를 분배</li>
<li>의미: &quot;이 예측을 만드는 데 얼마나 기여했을까?&quot;</li>
</ul>
<p>설명 목적이라면 LRP가 더 직관적인 결과를 제공한다.</p>
<hr>
<h1 id="6-한-줄-정리">6. 한 줄 정리</h1>
<ul>
<li><p><strong>Backpropagation</strong>은
→ “얼마나 바꿔야 하는가?”를 계산하는 알고리즘</p>
</li>
<li><p><strong>LRP</strong>는
→ “누가 얼마나 만들었는가?”를 계산하는 알고리즘</p>
</li>
</ul>
<p>같은 역방향 계산처럼 보이지만,</p>
<ul>
<li>하나는 <strong>최적화를 위한 미분</strong></li>
<li>하나는 <strong>출력을 분해하는 기여도 계산</strong></li>
</ul>
<p>이라는 점에서 본질적으로 다르다는 것을 알게되었다. 
해당 알고리즘을 바탕으로 어떻게 적용하여 현업 및 실무에 적용할지 고민하게 되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Analyzing Multi-Head Self-Attention: Specialized Heads Do the Heavy Lifting, the Rest Can Be Pruned]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Analyzing-Multi-Head-Self-Attention-Specialized-Heads-Do-the-Heavy-Lifting-the-Rest-Can-Be-Pruned</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Analyzing-Multi-Head-Self-Attention-Specialized-Heads-Do-the-Heavy-Lifting-the-Rest-Can-Be-Pruned</guid>
            <pubDate>Tue, 03 Mar 2026 13:07:55 GMT</pubDate>
            <description><![CDATA[<h3 id="analyzing-multi-head-self-attention-specialized-heads-do-the-heavy-lifting-the-rest-can-be-prunedhttpsaclanthologyorgp19-1580pdf">Analyzing Multi-Head Self-Attention: Specialized Heads Do the Heavy Lifting, the Rest Can Be Pruned(<a href="https://aclanthology.org/P19-1580.pdf">https://aclanthology.org/P19-1580.pdf</a>)</h3>
<h4 id="트랜스포머-속-엘리트-20를-찾아내는-수학적-인사고과">트랜스포머 속 엘리트 20%를 찾아내는 수학적 인사고과</h4>
<blockquote>
<p>48개의 어텐션 헤드 중 <strong>38개를 잘라내도 번역 품질이 거의 그대로</strong>라는 충격적인 사실.<br>ACL 2019 | Elena Voita et al. (Yandex, University of Amsterdam, University of Edinburgh)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>이 논문은 기계 번역 분야의 핵심인 트랜스포머(Transformer) 모델이 <strong>&#39;생각보다 게으르다&#39;</strong> 는 충격적인 사실을 밝혀낸 연구입니다.</p>
<p>트랜스포머는 여러 개의 헤드(Head)를 동시에 사용하는 &#39;다중 헤드 어텐션(Multi-head Attention)&#39; 덕분에 강력한 성능을 내는 것으로 알려져 왔습니다. 하지만 이 논문은 놀랍게도 그 많은 헤드 중 <strong>실제로 번역을 캐리하는 엘리트 헤드는 20%에 불과하고, 나머지 80%는 없어도 그만인 무임승차자</strong>라는 것을 입증했습니다.</p>
<p>저는 거대한 인공지능 내부를 현미경처럼 들여다보고, 나아가 수학적인 방법으로 불필요한 부품을 시원하게 잘라내는 이 논문의 접근 방식에 큰 매력을 느꼈습니다. 이 글을 통해 인공지능이 내부적으로 언어를 어떻게 이해하는지, 그리고 어떻게 하면 이 거대한 모델을 똑똑하고 가볍게 다이어트시킬 수 있는지 함께 파헤쳐 보겠습니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문을 제대로 이해하기 위해 알아야 할 필수 개념들을 가볍게 짚고 넘어가 봅시다.</p>
<h3 id="트랜스포머transformer와-어텐션attention">트랜스포머(Transformer)와 어텐션(Attention)</h3>
<p>오늘날 ChatGPT를 비롯한 대부분의 AI 모델을 지탱하는 핵심 기술입니다. 번역을 할 때 문장의 모든 단어에 집중하는 것이 아니라, 현재 번역할 단어와 <strong>&#39;가장 관련이 깊은 단어&#39;에만 집중(Attention)하는 기술</strong>입니다.</p>
<blockquote>
<p>&quot;I ate a delicious apple&quot;을 번역할 때 &#39;apple&#39;을 번역하는 순간에는 &#39;ate&#39;나 &#39;delicious&#39;에 강한 어텐션을 주는 방식입니다.</p>
</blockquote>
<p>수식으로 표현하면 다음과 같습니다.</p>
<p>$$Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$</p>
<h3 id="다중-헤드-어텐션-multi-head-attention">다중 헤드 어텐션 (Multi-head Attention)</h3>
<p>한 명의 똑똑한 전문가 대신, <strong>여러 명의 전문가(Head)를 두어 동시에 문장을 분석</strong>하게 하는 방식입니다.</p>
<table>
<thead>
<tr>
<th>이유</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>다양한 관점 확보</strong></td>
<td>문법 전문가, 의미 전문가 등 여러 시각에서 문장을 입체적으로 이해</td>
</tr>
<tr>
<td><strong>표현력 향상</strong></td>
<td>단일 헤드 대비 거의 1 BLEU 포인트 이상의 성능 향상</td>
</tr>
<tr>
<td><strong>구조</strong></td>
<td>트랜스포머는 보통 한 층에 8개 헤드 × 6개 층 = <strong>총 48개 헤드</strong></td>
</tr>
</tbody></table>
<h3 id="모델-경량화-pruning-가지치기">모델 경량화 (Pruning, 가지치기)</h3>
<p>학습이 끝난 인공지능 모델에서 불필요한 파라미터(신경망의 연결선)를 잘라내어 모델의 크기를 줄이고 속도를 높이는 기술입니다.</p>
<blockquote>
<p>AI 모델이 점점 거대해지면서 스마트폰 같은 작은 기기에 넣거나 서버 유지비를 줄이기 위해 &#39;다이어트&#39;가 필수가 되었습니다.</p>
</blockquote>
<p><strong>비전공자를 위한 요약</strong><br>기존에는 &quot;트랜스포머는 여러 명의 전문가(헤드)가 토론해서 번역을 잘한다!&quot;라고 믿어왔습니다. 그런데 이 논문은 <strong>&quot;진짜 다 일하는 거 맞아? 노는 전문가가 더 많은 거 아니야?&quot;</strong> 라는 합리적인 의심에서 출발합니다.</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 핵심 문제는 <strong>&quot;우리는 다중 헤드 어텐션의 내부를 너무 모른다&quot;</strong> 는 것입니다.</p>
<h3 id="기존-방식의-한계">기존 방식의 한계</h3>
<p>기존 연구자들은 &quot;이 모델이 번역을 잘하네? 여러 헤드가 각자 잘 협력했겠지!&quot;라고 뭉뚱그려 생각했습니다. 기껏 분석을 해도 수십 개 헤드의 점수를 그냥 <strong>평균 내버렸죠.</strong></p>
<p>이는 마치 조별 과제에서 A+를 받았다고 조원 5명 모두가 열심히 했다고 착각하는 것과 같습니다.</p>
<h3 id="이-논문이-해결하려는-3가지-질문">이 논문이 해결하려는 3가지 질문</h3>
<table>
<thead>
<tr>
<th>질문</th>
<th>조별 과제 비유</th>
</tr>
</thead>
<tbody><tr>
<td>48명의 헤드 중 <strong>진짜 기여한 에이스는 누구인가?</strong></td>
<td>밤새워 자료 조사한 조원은 누구인가?</td>
</tr>
<tr>
<td>그 에이스는 <strong>구체적으로 어떤 역할을 맡았는가?</strong></td>
<td>PPT 담당인가, 발표 담당인가?</td>
</tr>
<tr>
<td><strong>무임승차자를 빼버려도 여전히 A+를 받을 수 있는가?</strong></td>
<td>이름만 올린 조원을 제거해도 결과물이 나오는가?</td>
</tr>
</tbody></table>
<h3 id="이-문제를-해결하면-얻는-것">이 문제를 해결하면 얻는 것</h3>
<ol>
<li>블랙박스였던 AI의 내부 작동 방식을 투명하게 이해할 수 있습니다. <strong>(설명 가능성)</strong></li>
<li>무임승차자를 제거하여 AI를 훨씬 가볍고 빠르게 만들 수 있습니다. <strong>(경량화)</strong></li>
</ol>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>저자들은 이 문제를 해결하기 위해 <strong>&#39;분석&#39;과 &#39;제거&#39;라는 투 트랙(Two-track) 전략</strong>을 사용했습니다.</p>
<h3 id="전체-구조-에이스-찾기-→-역할-분석-→-부드럽게-해고하기">전체 구조: 에이스 찾기 → 역할 분석 → 부드럽게 해고하기</h3>
<ol>
<li><strong>LRP(역추적) 알고리즘으로 에이스 찾기</strong> — 번역 결과물에서 거꾸로 추적해 올라가며, 어떤 헤드가 가장 큰 수학적 기여를 했는지 점수를 매깁니다.</li>
<li><strong>에이스의 특기 파악하기</strong> — 점수가 높은 헤드들이 문장을 볼 때 어디에 집중하는지 분석합니다. 논문은 총 3가지 주특기를 발견했습니다.</li>
<li><strong>부드러운 스위치 달아주기 (Hard Concrete)</strong> — 모델의 각 헤드에 확률적으로 작동하는 &#39;스위치&#39;를 답니다.</li>
<li><strong>벌점 주며 다시 학습시키기</strong> — 켜져 있는 스위치가 많을수록 모델에게 벌점($L_0$ 페널티)을 주며 학습을 시킵니다. 그러면 모델은 벌점을 안 받으려고 스스로 안 쓰는 헤드의 스위치를 꺼버립니다.</li>
</ol>
<h3 id="발견된-3가지-엘리트-헤드-유형">발견된 3가지 엘리트 헤드 유형</h3>
<table>
<thead>
<tr>
<th>헤드 유형</th>
<th>역할</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><strong>위치 헤드 (Positional)</strong></td>
<td>바로 인접한 단어 보기</td>
<td>90% 이상의 확률로 ±1 위치 단어에 집중</td>
</tr>
<tr>
<td><strong>문법 헤드 (Syntactic)</strong></td>
<td>주어-동사, 목적어 등 문법 관계 파악</td>
<td>nsubj, dobj, amod, advmod 관계 탐지</td>
</tr>
<tr>
<td><strong>희귀 단어 헤드 (Rare words)</strong></td>
<td>문장 내 가장 생소한 단어에 집중</td>
<td>1층에 위치, LRP 기여도 압도적 1위</td>
</tr>
</tbody></table>
<h3 id="핵심-아이디어-직관적-이해-💡">핵심 아이디어 직관적 이해 💡</h3>
<p><strong>🍲 비유 1: 역추적 기여도 (LRP)</strong></p>
<p>식당에서 엄청 맛있는 찌개가 나왔습니다. 주방장(LRP)이 레시피를 거꾸로 짚어보며 고기 50%, 마늘 30%, 파 20%의 지분으로 맛이 났다는 걸 정확한 숫자로 계산해 내는 것과 같습니다.</p>
<p><strong>💡 비유 2: 부드러운 스위치 (Hard Concrete 완화)</strong></p>
<p>방에 전등이 몇 개 켜졌는지 세서 전기세를 매겨야 합니다. 그런데 컴퓨터는 &#39;켜짐(1)&#39;과 &#39;꺼짐(0)&#39;처럼 계단식으로 확 꺾이는 그래프는 학습을 못 합니다 <strong>(미분 불가)</strong>. 그래서 조광기(다이얼)처럼 <strong>&quot;이 전구는 빛이 80% 켜져 있으니 0.8개로 쳐줄게&quot;</strong> 라고 부드러운 확률 곡선으로 바꿔준 수학적 꼼수입니다. 덕분에 컴퓨터가 스스로 잉여 헤드의 다이얼을 서서히 줄여 끌 수 있게 되었습니다.</p>
<hr>
<h3 id="📊-figure-1-lrp-기여도-confidence-헤드-기능-시각화">📊 Figure 1: LRP 기여도, Confidence, 헤드 기능 시각화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/a77ba726-8d6c-4955-b872-2e4da1e8b73b/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 각 레이어별로 헤드의 LRP 기여도 순위, 확신도(Confidence), 그리고 위치/문법/희귀 단어 등 기능 유형을 색상으로 나타낸 히트맵</li>
<li><strong>핵심 메시지:</strong> LRP 점수가 높은 헤드와 Confidence가 높은 헤드가 상당 부분 일치하며, 이들은 대부분 위치 헤드(보라색)나 문법 헤드(초록색)에 해당합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>&quot;중요한 헤드는 자기가 봐야 할 단어를 확신 있게 본다&quot;는 것이 수치로도 증명됩니다. 특히 1층의 희귀 단어 헤드는 LRP 기여도가 압도적인 1위지만 Confidence는 오히려 낮습니다. 어려운 단어를 찾느라 여러 단어를 넓게 훑기 때문입니다. 이 예외 케이스가 모델을 더 입체적으로 이해하게 해줬습니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2-핵심-헤드-제거-비율에-따른-bleu-점수-변화">📊 Figure 2 (핵심): 헤드 제거 비율에 따른 BLEU 점수 변화</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/a7a20e8c-b0fb-4c85-93a5-3cdef54d98be/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 헤드를 하나씩 제거해 나갈 때 번역 품질(BLEU 스코어)이 어떻게 변하는지 보여주는 핵심 그래프</li>
<li><strong>실험 설정:</strong> X축은 &#39;남은 인코더 헤드의 수&#39;, Y축은 &#39;번역 품질 점수(BLEU)&#39;. EN-RU(영어→러시아어) 기준</li>
<li><strong>핵심 메시지:</strong> WMT 데이터 기준 <strong>48개 중 38개를 제거해도 BLEU 하락이 고작 0.15점</strong>이며, OpenSubtitles 데이터에서는 <strong>44개를 제거(4개만 남겨도) BLEU 하락이 0.25점</strong>에 불과합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>그래프의 선이 초반에는 평행하게 쭉 유지되다가, 헤드를 80% 이상 쳐내는 극후반부에 가서야 점수가 뚝 떨어집니다. 이는 모델 내부에 잉여 부품이 상상 이상으로 많았다는 결정적 증거입니다. 무거운 트랜스포머 모델을 훨씬 가볍게 만들 수 있다는 실질적인 희망을 보여주는 데이터입니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 자신들의 가설을 증명하기 위해 치밀한 실험을 설계했습니다.</p>
<table>
<thead>
<tr>
<th>실험 항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>언어 조합</strong></td>
<td>영어→러시아어, 영어→독일어, 영어→프랑스어 (3가지 어순 패턴)</td>
</tr>
<tr>
<td><strong>데이터 도메인</strong></td>
<td>WMT(딱딱한 뉴스 기사) + OpenSubtitles(부드러운 영화 자막)</td>
</tr>
<tr>
<td><strong>학습 데이터 규모</strong></td>
<td>250만 문장 쌍 (언어쌍별 동일하게 통제)</td>
</tr>
</tbody></table>
<h3 id="평가-지표">평가 지표</h3>
<ol>
<li><strong>LRP 기여도 점수</strong> — 수학적으로 얼마나 기여했는가?</li>
<li><strong>문법 정확도</strong> — 헤드가 짚어낸 단어 관계가 실제 언어학적 문법과 얼마나 일치하는가?</li>
<li><strong>BLEU 스코어</strong> — 최종 번역된 문장이 사람이 보기에 얼마나 자연스러운가?</li>
</ol>
<h3 id="결과-요약">결과 요약</h3>
<blockquote>
<p><strong>인코더 헤드의 80%를 제거해도 성능이 그대로 유지되었습니다.</strong><br>끝까지 살아남은 20%의 에이스 헤드들은 정확히 <strong>&#39;인접 단어 보기&#39;, &#39;문법 구조 파악&#39;, &#39;희귀 단어 집중&#39;</strong> 이라는 확실한 자기 전공을 가지고 있었습니다.</p>
</blockquote>
<p>또한 디코더에서 인코더를 참조하는 <strong>디코더-인코더 어텐션 헤드(번역의 생명줄)</strong> 는 자르려고 하면 성능이 확 떨어지며 강하게 저항했습니다. 반대로 <strong>인코더 자기 어텐션 헤드</strong>가 가장 먼저 제거되었습니다.</p>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>이중 교차 검증의 논리적 완벽함</strong> — 단순히 &quot;얘가 중요하다&quot;라고 관찰하는 데 그치지 않고, &quot;진짜? 그럼 걔 빼고 다 지워볼게. 봐, 진짜 얘네만 일하잖아!&quot;라며 LRP 분석과 실제 가지치기 실험으로 두 번 검증했습니다.</li>
<li><strong>Fine-tuning 방식의 우월성</strong> — 처음부터 적은 헤드로 학습한 모델보다, 큰 모델을 충분히 학습시킨 후 가지치기한 모델이 항상 더 높은 성능을 보였습니다.</li>
</ol>
<h3 id="❌-설계상의-트레이드오프">❌ 설계상의 트레이드오프</h3>
<ol>
<li><strong>이중 학습 비용</strong> — 모델을 가볍게 만들기 위해 이미 다 학습된 모델에 스위치를 달고 <strong>다시 한번 무거운 파인튜닝을 돌려야 합니다.</strong> 최종 결과물은 가볍지만 그 과정에서 서버 비용과 시간이 이중으로 드는 딜레마가 있습니다.</li>
<li><strong>영어 문법 중심의 한계</strong> — 영어를 기준으로만 분석을 진행했습니다. 한국어나 일본어처럼 어순이 완전히 뒤집히는 SOV 언어에서도 똑같은 엘리트 헤드들이 등장할지는 아직 미지수입니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<p>가지치기를 언어쌍과 도메인에 맞게 동적으로 설정하는 <strong>&#39;어댑티브 가지치기&#39;</strong> 를 도입한다면, 한국어-영어처럼 어순이 극단적으로 다른 언어쌍에서도 더 정교한 엘리트 헤드 분석이 가능할 것으로 보입니다.</p>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>딥러닝이 아무리 블랙박스라고 해도, 그 안에는 결국 <strong>&#39;주어-동사를 찾는 녀석&#39;, &#39;제일 어려운 단어를 고민하는 녀석&#39;</strong> 처럼 인간의 언어 처리 방식과 놀랍도록 닮은 특화된 요원들이 존재한다는 사실이 소름 돋게 신기했습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>왜 미분 불가능한 꺾인 선을 부드러운 확률 곡선(Hard Concrete)으로 펴줘야 하는지, 그 수학적 꼼수의 필요성을 완벽히 이해했습니다.</p>
<blockquote>
<p>컴퓨터에게 &quot;너 해고야!&quot;라고 갑자기 통보하는 게 아니라 &quot;너 성과가 안 좋으니 월급을 10%씩 줄일 거야&quot;라고 서서히 압박해서 <strong>스스로 나가게 만드는 과정</strong>이 핵심이었습니다.</p>
</blockquote>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>이 기법은 번역기뿐만 아니라, 거대한 생성형 AI(LLM)를 스마트폰에 욱여넣기 위한 <strong>&#39;온디바이스 AI(On-device AI)&#39; 최적화 기술</strong>에 핵심 아이디어로 쓰일 수 있겠다고 생각했습니다. 어떤 헤드가 진짜 일하는지 먼저 파악하고 나서 모델을 설계한다면, 처음부터 훨씬 효율적인 경량 아키텍처를 만들 수 있을 것입니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>다중 헤드 어텐션에서 진짜 번역에 기여하는 헤드는 누구이고, 안 쓰는 헤드는 어떻게 안전하게 잘라낼 수 있는가?</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>LRP 알고리즘으로 에이스를 찾고, Hard Concrete 분포 기반 $L_0$ 완화 스위치로 잉여 헤드가 스스로 꺼지도록 유도</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>전체 48개 헤드의 약 20%(10개)만 위치·문법·희귀 단어를 전담하는 엘리트이며, 나머지 80%(38개)를 제거해도 BLEU 하락 0.15점에 불과함을 증명</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>가설(얘가 에이스다)을 세우고, 물리적 실험(얘네 빼고 다 지워봄)으로 완벽하게 입증한 <strong>LRP 분석 + 가지치기 이중 교차 검증</strong> 구조</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>영어 중심의 분석으로, 한국어·일본어 등 어순이 극단적으로 다른 언어에서도 같은 결과가 나올지 검증되지 않음</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>온디바이스 AI 경량화, LLM 구조 설계 최적화, 그리고 하드웨어 단의 실질적 연산 속도 향상에 대한 추가 연구</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>트랜스포머의 48개 헤드 중 80%는 무임승차자였으며, LRP로 에이스를 찾아내고 Hard Concrete로 잡연을 해고하는 이중 전략으로 AI 내부의 블랙박스를 걷어낸 혁신적인 분석 연구다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Rethinking Attention with Performers]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Rethinking-Attention-with-Performers</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Rethinking-Attention-with-Performers</guid>
            <pubDate>Mon, 02 Mar 2026 06:04:11 GMT</pubDate>
            <description><![CDATA[<h3 id="rethinking-attention-with-performershttpsarxivorgpdf200914794">Rethinking Attention with Performers(<a href="https://arxiv.org/pdf/2009.14794">https://arxiv.org/pdf/2009.14794</a>)</h3>
<h4 id="메모리-폭발-없이-무한히-긴-문맥을-처리하는-트랜스포머">메모리 폭발 없이 무한히 긴 문맥을 처리하는 트랜스포머</h4>
<blockquote>
<p>복잡한 어텐션 연산량을 선형 시간(Linear-Time)으로 확 줄이면서도 정보 손실이 전혀 없는 <strong>FAVOR+</strong> 의 수학적 원리를 파헤쳐 봅니다.</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>오늘 리뷰할 논문은 효율적인 트랜스포머(Efficient Transformer) 연구의 마스터피스 중 하나로 꼽히는 <strong>&quot;Rethinking Attention with Performers&quot;</strong> 입니다.</p>
<p>요즘 대형 언어 모델(LLM)을 써보시면 문맥 길이가 길어질수록 메모리가 펑펑 터지는 &#39;OOM(Out of Memory)&#39; 문제를 다들 겪어보셨을 텐데요. 이 논문은 기존의 복잡한 어텐션(Attention) 계산 순서를 기발한 수학적 마법(FAVOR+)으로 뒤집어서, 메모리 사용량을 기하급수적 폭발에서 선형적인 증가로 확 줄여버린 놀라운 아이디어를 담고 있습니다.</p>
<p>이 글을 끝까지 읽으시면, 복잡한 수식의 늪에 빠지지 않고도 어떻게 트랜스포머가 한계를 극복하여 수만 자의 텍스트나 긴 단백질 서열을 한 번에 스윽 읽어내는지 그 직관적인 원리를 깨닫게 되실 겁니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심으로 들어가기 전에, 왜 이런 연구가 필요했는지 배경지식을 가볍게 짚고 넘어가 보겠습니다.</p>
<h3 id="어텐션attention-메커니즘">어텐션(Attention) 메커니즘</h3>
<p>트랜스포머 모델의 심장은 바로 <strong>어텐션</strong>입니다. 문장 속 단어들이 서로 얼마나 연관되어 있는지를 점수로 매기는 과정이죠.</p>
<blockquote>
<p>&quot;나는 어제 아주 맛있는 피자를 먹었다&quot;라는 문장에서 &#39;먹었다&#39;라는 단어가 &#39;피자&#39;와 강하게 연결되어 있음을 파악하는 능력입니다.</p>
</blockquote>
<h3 id="무엇이-문제인가-시간공간-복잡도">무엇이 문제인가? (시간/공간 복잡도)</h3>
<p>단어의 총 개수(시퀀스 길이)를 $L$이라고 해볼게요. 기존 어텐션은 모든 단어가 다른 모든 단어와 빠짐없이 <strong>1:1로 인사를 나눠야</strong> 합니다.</p>
<table>
<thead>
<tr>
<th>단어 수</th>
<th>필요한 인사 횟수</th>
</tr>
</thead>
<tbody><tr>
<td>10개</td>
<td>100번</td>
</tr>
<tr>
<td>1만 개</td>
<td><strong>1억 번</strong></td>
</tr>
</tbody></table>
<p>이를 수학적으로는 계산량과 메모리 소모가 $O(L^2)$ 단위로 커진다고 표현합니다.</p>
<h3 id="왜-이-문제를-풀어야-할까요">왜 이 문제를 풀어야 할까요?</h3>
<p>AI가 똑똑해지려면 책 한 권을 통째로 읽거나, 고해상도 이미지를 한 번에 분석하거나, 엄청나게 긴 DNA 염기서열을 봐야 합니다. 하지만 문맥이 조금만 길어져도 GPU 메모리가 제곱으로 팽창하며 터져버리기 때문에, 이 $O(L^2)$의 벽을 허무는 것은 AI 학계의 가장 시급한 숙제였습니다.</p>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 꼬집는 가장 근본적인 문제는 <strong>&quot;Softmax 함수의 병목 현상&quot;</strong> 입니다. 어텐션을 계산할 때는 반드시 Softmax라는 함수를 거쳐야 하는데, 이 녀석 때문에 무조건 거대한 $L \times L$ 크기의 표(행렬)를 메모리에 만들어야만 합니다.</p>
<h3 id="기존-방식의-한계">기존 방식의 한계</h3>
<p>Performer 이전에도 이 문제를 풀려는 시도는 아주 많았습니다. 보통 두 가지 꼼수를 썼습니다.</p>
<table>
<thead>
<tr>
<th>방식</th>
<th>설명</th>
<th>치명적 단점</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Sparse Attention</strong></td>
<td>&quot;너무 머니까 내 주변 10단어하고만 연결하자!&quot;</td>
<td>멀리 떨어진 단어 간의 의미를 놓침</td>
</tr>
<tr>
<td><strong>Local Attention</strong></td>
<td>&quot;긴 글을 100단어씩 뚝뚝 끊어서 보자!&quot;</td>
<td>문맥이 조각나며 정보 유실 발생</td>
</tr>
</tbody></table>
<h3 id="직관적-비유-🤝">직관적 비유 🤝</h3>
<p>1,000명의 사람이 모인 네트워킹 파티장이 있습니다.</p>
<ul>
<li><strong>기존 어텐션:</strong> 1,000명이 모두 서로 1:1로 명함을 교환합니다. (100만 번의 악수 필요, 극도의 체력 소모)</li>
<li><strong>기존 꼼수들:</strong> &quot;자기 양옆에 있는 사람 5명하고만 인사하세요!&quot; (정보의 파편화 발생)</li>
<li><strong>Performer가 풀려는 것:</strong> &quot;어떻게 하면 누구 하나 소외되지 않고 1,000명의 정보를 완벽히 공유하면서도, 악수 횟수를 획기적으로 줄일 수 있을까?&quot;</li>
</ul>
<blockquote>
<p><strong>Performer의 목표</strong><br>정보의 손실(꼼수) 전혀 없이, 완벽하게 기존 어텐션과 똑같은 결과를 내면서도 메모리만 $O(L)$ 크기로 획기적으로 줄이는 것.</p>
</blockquote>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>Performer는 <strong>FAVOR+ (Fast Attention Via positive Orthogonal Random features)</strong> 라는 강력한 수학적 무기를 도입하여 이 문제를 해결합니다.</p>
<h3 id="핵심-아이디어">핵심 아이디어</h3>
<p>원래 어텐션의 수식은 이렇습니다.</p>
<p>$$Attention = \text{Softmax}(Q \cdot K^T) \cdot V$$</p>
<p>괄호 안의 $Q$와 $K$를 내적한 뒤 $\text{Softmax}$를 씌우는 과정이 문제입니다. 지수 함수($\exp$)가 포함되어 있어서 괄호를 풀고 분배/결합 법칙을 쓸 수가 없습니다. 무조건 $Q$와 $K$를 먼저 곱해 어마어마한 $L \times L$ 행렬을 만들어야 하죠.</p>
<p>저자들은 여기서 천재적인 접근을 합니다.</p>
<blockquote>
<p><strong>&quot;Softmax 자물쇠를 부수지 말고, 아주 비슷한 복제 키를 만들어서 쪼개버리자!&quot;</strong></p>
</blockquote>
<p>수학의 커널 근사(Kernel Approximation) 기법을 이용해 식을 아래와 같이 변형합니다.</p>
<p>$$Attention \approx \phi(Q) \cdot (\phi(K)^T \cdot V)$$</p>
<p>$\phi$라는 마법의 필터(무작위 특성 투영)를 씌웠더니, 묶여있던 $Q$와 $K$가 <strong>분리</strong>되었습니다. 이제 괄호의 위치를 바꿀 수 있게 된 겁니다! 거대한 행렬을 만들 필요 없이, 덩치가 작은 $\phi(K)^T$와 $V$를 먼저 곱해버리고 나중에 $Q$를 곱하면 끝납니다.</p>
<h3 id="직관적-비유-2가지-💡">직관적 비유 2가지 💡</h3>
<p><strong>🧮 비유 1: 계산기 괄호 옮기기 (결합 법칙 비유)</strong></p>
<p>메모리 한도가 숫자 &#39;100&#39;까지인 계산기가 있습니다.</p>
<ul>
<li><strong>(10 × 10) × 2</strong> → 괄호 안을 먼저 계산하면 100이 꽉 차서 계산기가 멈춰버립니다.</li>
<li><strong>10 × (10 × 2)</strong> → 10 × 20이 되어, 중간 과정에서 메모리가 터지지 않고 무사히 정답 200을 얻을 수 있습니다.</li>
</ul>
<p>Performer는 행렬 곱셈에서 이 <strong>&#39;괄호 옮기기&#39;</strong> 를 가능하게 한 것입니다.</p>
<p><strong>🧚 비유 2: 브로커(요정) 배치 비유</strong></p>
<p>다시 파티장으로 돌아가 보죠. 1,000명이 1:1로 악수하는 대신, 파티장 한가운데에 <strong>5명의 정보 브로커 요정($\phi$ 차원)</strong> 을 배치합니다.</p>
<ol>
<li>1,000명의 사람들은 이 5명의 요정에게만 가서 자기 정보를 줍니다. (5,000번 대화)</li>
<li>요정들은 정보를 싹 정리해서 다시 1,000명에게 뿌려줍니다.</li>
</ol>
<p>100만 번 필요했던 대화가 순식간에 줄어들면서도 모두가 정보를 알게 됩니다!</p>
<hr>
<h3 id="📊-figure-1-정규-어텐션과-performer-연산-구조-비교">📊 Figure 1: 정규 어텐션과 Performer 연산 구조 비교</h3>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 일반 트랜스포머의 행렬 곱셈 순서와 Performer의 행렬 곱셈 순서를 시각적인 블록으로 비교한 도식</li>
<li><strong>핵심 메시지:</strong> 기존 방식은 $L \times L$이라는 거대한 사각형 블록이 중간에 떡하니 만들어지는 반면, Performer는 거대한 사각형 대신 <strong>얇고 긴 직사각형 형태</strong>를 유지하며 끝까지 연산이 흘러갑니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>결국 행렬을 어떤 순서로 묶어서 곱하느냐(결합 법칙)의 차이가 메모리 점유율의 형태를 완전히 바꿔버린다는 점을 한눈에 알 수 있었습니다. 이 논문의 핵심 기여인 <strong>&quot;공간 복잡도 $O(L)$ 달성&quot;</strong> 을 눈으로 가장 명확하게 증명하는 도식입니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2-시퀀스-길이에-따른-시간메모리-소모-그래프">📊 Figure 2: 시퀀스 길이에 따른 시간/메모리 소모 그래프</h3>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> X축은 입력 데이터의 길이(시퀀스 길이), Y축은 처리 속도(Time)와 메모리(Memory) 소모량</li>
<li><strong>핵심 메시지:</strong> 일반 트랜스포머의 그래프는 길이가 길어질수록 롤러코스터처럼 가파르게 위로 솟구치는 반면, Performer의 그래프는 <strong>완만한 직선(선형적 증가)</strong> 을 그립니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>데이터가 4,000자만 넘어가도 기존 모델은 GPU 메모리가 터져서 죽어버리지만, Performer는 6만 자가 넘어가도 아주 평온하게 버팁니다. 이론으로 수립한 수학 공식이 <strong>실제 하드웨어 인프라에서도 완벽하게 작동</strong>하여 병목을 없앴음을 증명하는 실험적 결과입니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 이 마법의 공식이 진짜로 성능 하락 없이 작동하는지 확인하기 위해 아주 가혹한 환경에서 테스트를 진행했습니다.</p>
<table>
<thead>
<tr>
<th>태스크</th>
<th>내용</th>
<th>결과</th>
</tr>
</thead>
<tbody><tr>
<td><strong>픽셀 예측</strong></td>
<td>고해상도 이미지를 1차원 픽셀로 길게 늘어뜨려 입력</td>
<td>65,536 길이 시퀀스에서 메모리 초과 없이 학습 완료</td>
</tr>
<tr>
<td><strong>단백질 서열 분석</strong></td>
<td>무지막지하게 긴 아미노산 서열 구조 학습</td>
<td>기존 $O(L^2)$ 트랜스포머와 정확도 그래프가 완벽히 일치</td>
</tr>
</tbody></table>
<h3 id="결과-해석">결과 해석</h3>
<p>더 놀라운 것은 정확도(Accuracy) 그래프가 기존 $O(L^2)$ 트랜스포머와 <strong>소름 돋게 완벽히 겹쳤다</strong>는 점입니다.</p>
<blockquote>
<p>연산량을 쥐어짜 내기 위해 꼼수를 쓴 것이 아니라, 수학적으로 정답을 완벽하게 근사(Unbiased estimation)했기 때문에 모델이 전혀 멍청해지지 않았음을 증명한 것입니다. 다른 꼼수 기반의 경량화 모델(Reformer, Linformer 등)과 비교했을 때도 압도적인 성능 유지력을 보여주었습니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>무손실 압축 같은 느낌</strong> — 정보를 버리지 않고 전체 문맥(Global context)을 모두 활용합니다.</li>
<li><strong>뛰어난 호환성</strong> — 기존에 학습해둔 트랜스포머 모델에서 어텐션 부품만 Performer로 갈아 끼우고 살짝 튜닝만 해주면 바로 작동합니다. <strong>(Plug-and-play 가능)</strong></li>
</ol>
<h3 id="❌-한계점-및-트레이드오프">❌ 한계점 및 트레이드오프</h3>
<ol>
<li><strong>짧은 문장에서는 오히려 느림</strong> — &quot;브로커 요정&quot;들을 소환하고 수학적 매핑($\phi$)을 거치는 준비 작업 때문에, 데이터 길이가 짧을 때(예: 512자 이하)는 기존 방식보다 실질적인 연산 속도가 오히려 조금 더 느려지는 배보다 배꼽이 더 큰 상황이 발생할 수 있습니다.</li>
<li><strong>Causal Masking 구현의 난해함</strong> — 단어를 순서대로 생성해야 하는 GPT 같은 모델에서는 뒤의 단어를 미리 커닝하지 못하도록 막아야 합니다. Performer 구조에서 이를 구현하려면 <strong>누적합(Prefix-sum)</strong> 이라는 복잡한 처리가 필요해 구현 난이도가 꽤 높습니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<p>문장 길이에 따라 $\phi$ 매핑의 차원 수를 동적으로 조절하는 <strong>어댑티브 FAVOR+</strong> 구조를 설계한다면, 짧은 문장에서의 오버헤드 문제를 해결하면서도 긴 문장에서의 강점을 그대로 살릴 수 있을 것으로 보입니다.</p>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>AI 연구에서 단순히 &quot;이거저거 깎아내서 가볍게 만들자!&quot;라는 엔지니어링적 접근이 아니라, 수학의 깊은 원리(커널 이론, 직교성 등)를 가져와 <strong>근본적인 수식 자체를 재설계</strong>해 버린 저자들의 뷰티풀한 접근 방식에 큰 감명을 받았습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>Softmax 안에 갇혀있는 변수들을 독립적으로 꺼내어 행렬의 결합 법칙을 활용한다는 큰 그림은 아주 직관적으로 와닿았습니다.</p>
<blockquote>
<p>어텐션을 통째로 구하지 않고, Key와 Value를 먼저 버무려 놓는다는 <strong>발상의 전환</strong>이 핵심이었습니다.</p>
</blockquote>
<h3 id="아직-헷갈리는-부분">아직 헷갈리는 부분</h3>
<p>오차를 줄이기 위해 사용했다는 <strong>&#39;긍정 직교 무작위 특성(Positive Orthogonal Random Features)&#39;</strong> 의 구체적인 수학적 증명 과정은 수식이 너무 빽빽해서 아직 100% 소화하지는 못했습니다. 왜 하필 무작위 벡터들을 서로 &#39;수직(직교)&#39;으로 만들어야 에러율의 분산(Variance)이 최소화되는지에 대해서는 커널 이론을 좀 더 파봐야 할 것 같습니다.</p>
<h3 id="어디에-응용할-수-있을까">어디에 응용할 수 있을까?</h3>
<p>요즘 뜨고 있는 긴 문서 요약(Long-document QA) 서비스나, 수만 시간 분량의 비디오 프레임 단위 분석, 혹은 유전자 염기서열 분석 같은 <strong>Bio-Informatics</strong> 분야에 이 구조를 도입하면 기존의 한계를 가볍게 뛰어넘는 혁신적인 모델이 나올 수 있겠다고 생각했습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>트랜스포머의 어텐션은 문맥이 길어질수록 메모리와 계산량이 $O(L^2)$으로 폭발하여 긴 데이터 처리 불가</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>FAVOR+ 기법을 도입하여 Softmax 수식을 쪼갠 뒤 <strong>행렬 곱셈의 순서를 변경</strong> (괄호 옮기기 신공)</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>정보 손실 전혀 없이 기존 어텐션을 완벽하게 근사하면서 시간/공간 복잡도를 선형 $O(L)$ 수준으로 압축</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>특정 도메인에 얽매이지 않고 수학적 증명을 통해 어떤 데이터든 100% 성능 보장이 가능함을 입증한 우아함</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>문장 길이가 짧을 때는 구조적 복잡성 때문에 오히려 속도 이득을 보기 어렵다는 태생적인 트레이드오프</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>텍스트를 넘어 극단적으로 긴 DNA/RNA 분석 등 <strong>바이오 AI 모델 설계</strong>의 새로운 표준 뼈대로 활용 가능</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>Performer는 Softmax라는 자물쇠를 수학적 복제 키로 열어 행렬 곱셈의 순서를 뒤집음으로써, 정보 손실 없이 트랜스포머의 메모리 폭발 문제를 우아하게 해결한 혁명적인 아키텍처다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Online and Linear-Time Attention by Enforcing Monotonic Alignments]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Online-and-Linear-Time-Attention-by-Enforcing-Monotonic-Alignments</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Online-and-Linear-Time-Attention-by-Enforcing-Monotonic-Alignments</guid>
            <pubDate>Sat, 28 Feb 2026 13:21:01 GMT</pubDate>
            <description><![CDATA[<h2 id="온디바이스-실시간-ai를-위한-직진하는-어텐션">온디바이스 실시간 AI를 위한 직진하는 어텐션</h2>
<blockquote>
<p>데이터를 끝까지 기다리지 않고, 한 방향으로 스캔하며 즉각 결과를 뱉어내는 <strong>단조 어텐션(Monotonic Attention)</strong> 을 파헤쳐 봅니다. (<a href="https://arxiv.org/pdf/1704.00784">https://arxiv.org/pdf/1704.00784</a>)</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-%EC%84%9C%EB%A1%A0">서론</a></li>
<li><a href="#2-background">Background</a></li>
<li><a href="#3-problem-definition">Problem Definition</a></li>
<li><a href="#4-proposed-method--approach">Proposed Method / Approach</a></li>
<li><a href="#5-experiments--results">Experiments &amp; Results</a></li>
<li><a href="#6-discussion">Discussion</a></li>
<li><a href="#7-my-insights">My Insights</a></li>
<li><a href="#8-summary">Summary</a></li>
</ol>
<hr>
<h2 id="1-서론">1. 서론</h2>
<p>최근 스마트 홈 제어를 위한 온디바이스 음성 AI를 연구하면서, 사용자 명령에 즉각적으로 반응하는 실시간 처리의 필요성을 뼈저리게 느꼈습니다.</p>
<p>기존의 뛰어난 어텐션(Attention) 모델들은 문장이 끝날 때까지 묵묵히 기다렸다가 한 번에 연산을 시작하는 느린 구조라 엣지 기기에 올리기엔 너무 무거웠습니다.</p>
<p>이 논문은 데이터를 끝까지 기다리지 않고 한 방향으로 스캔하며 &#39;즉각적으로&#39; 결과를 뱉어내는 <strong>단조 어텐션(Monotonic Attention)</strong> 을 제안합니다. 복잡한 어텐션 연산량을 선형 시간(Linear-Time)으로 확 줄이면서도 실시간 스트리밍 처리를 가능하게 만든 수학적 마법을 함께 파헤쳐 보겠습니다.</p>
<hr>
<h2 id="2-background">2. Background</h2>
<p>논문의 핵심을 파악하기 위해 꼭 알아야 할 배경지식을 먼저 정리합니다.</p>
<h3 id="어텐션attention-메커니즘">어텐션(Attention) 메커니즘</h3>
<p>어텐션은 인공지능이 긴 문장을 처리할 때 &quot;어느 단어에 집중할지&quot;를 결정하는 기술입니다. 기존의 <strong>소프트 어텐션(Soft Attention)</strong> 은 결과를 하나 뱉어낼 때마다 입력된 모든 단어를 처음부터 끝까지 다 훑어보고 확률을 계산합니다.</p>
<h3 id="오프라인offline-vs-온라인online-처리">오프라인(Offline) vs 온라인(Online) 처리</h3>
<table>
<thead>
<tr>
<th>방식</th>
<th>설명</th>
<th>비유</th>
</tr>
</thead>
<tbody><tr>
<td><strong>오프라인</strong></td>
<td>입력이 완전히 끝날 때까지 기다린 후 처리</td>
<td>강연이 다 끝난 뒤 번역본을 나눠주는 번역가</td>
</tr>
<tr>
<td><strong>온라인</strong></td>
<td>입력이 들어오는 족족 실시간으로 처리</td>
<td>강연자가 말하는 동시에 통역을 내뱉는 동시통역사</td>
</tr>
</tbody></table>
<h3 id="선형-시간linear-time의-의미">선형 시간(Linear-Time)의 의미</h3>
<p>데이터의 길이가 $N$일 때, 기존 소프트 어텐션은 $N \times N$번의 <em>이차 시간</em> 계산을 해야 합니다. 데이터가 길어질수록 컴퓨터가 과로사하게 됩니다.</p>
<p>반면 <strong>선형 시간</strong>은 데이터가 늘어난 딱 그만큼($N$)만 계산량이 늘어나는 아주 효율적인 상태를 말합니다.</p>
<blockquote>
<p>온디바이스 환경이나 실시간 스트리밍 서비스에서는 메모리와 속도 제한이 극심합니다. 오프라인/이차 시간 복잡도를 온라인/선형 시간으로 바꾸는 것은 반드시 풀어야 할 숙제였습니다.</p>
</blockquote>
<hr>
<h2 id="3-problem-definition">3. Problem Definition</h2>
<p>이 논문이 정조준하고 있는 문제는 명확합니다.</p>
<blockquote>
<p><strong>&quot;기존 어텐션은 너무 많이 쳐다보고, 너무 오래 기다린다.&quot;</strong></p>
</blockquote>
<p>소프트 어텐션은 문장의 첫 번째 단어를 번역할 때도 문장 끝까지 다 훑어봅니다. 두 번째 단어를 번역할 때도 또 문장 끝까지 훑어봅니다. 이로 인해 두 가지 치명적인 한계가 발생합니다.</p>
<table>
<thead>
<tr>
<th>한계</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>지연 시간(Latency) 폭발</strong></td>
<td>사용자의 말이 끝나기 전에는 단 하나의 결과도 화면에 띄워줄 수 없음</td>
</tr>
<tr>
<td><strong>메모리 초과</strong></td>
<td>긴 음성 신호나 문서 처리 시 연산량이 제곱으로 불어나 메모리가 터짐</td>
</tr>
</tbody></table>
<h3 id="실제-사례-비유-🚗">실제 사례 비유 🚗</h3>
<p>자율주행 자동차가 카메라로 앞을 보고 있다고 가정해 봅시다.</p>
<ul>
<li><strong>기존 방식:</strong> &quot;10초짜리 영상이 다 녹화될 때까지 기다렸다가, 10초를 다 분석하고 나서 브레이크를 밟는&quot; 무서운 방식</li>
<li><strong>우리가 원하는 것:</strong> &quot;영상이 들어오는 매 순간 위험을 감지하면 즉시 브레이크를 밟는&quot; 시스템</li>
</ul>
<p>이 문제를 해결하면 AI는 훨씬 가벼워지고 응답 속도는 빛처럼 빨라집니다.</p>
<hr>
<h2 id="4-proposed-method--approach">4. Proposed Method / Approach</h2>
<p>저자들은 이 문제를 해결하기 위해 <strong>단조 정렬(Monotonic Alignment)</strong> 이라는 기발한 아이디어를 도입합니다.</p>
<h3 id="전체-구조">전체 구조</h3>
<p>모델은 입력 데이터를 왼쪽에서 오른쪽으로 <strong>딱 한 번만</strong> 스캔합니다. 스캔하다가 &quot;아, 여기서 정답을 뱉어야겠다!&quot; 싶으면 출력을 내보내고, 멈췄던 그 자리부터 다시 앞으로 스캔을 이어갑니다. <strong>절대 뒤로 되돌아가지 않습니다.</strong></p>
<h3 id="핵심-아이디어-비유">핵심 아이디어 비유</h3>
<p><strong>🍽️ 비유 1: 뷔페의 일방통행 룰</strong>
기존 모델은 뷔페의 모든 코너를 다 둘러본 뒤에야 첫 접시를 채웁니다. 단조 어텐션은 일렬로 늘어선 뷔페 줄을 걸어가며 &quot;이거 담을까 말까?&quot;만 즉시 결정합니다. 지나친 음식은 다시 돌아가서 뜰 수 없습니다.</p>
<p><strong>💘 비유 2: 소개팅 앱(틴더) 스와이프</strong>
상대방의 프로필 카드가 순서대로 나옵니다. 카드를 보고 &#39;선택(1)&#39;할지 &#39;패스(0)&#39;할지 결정합니다. 한 번 패스한 카드는 다시 볼 수 없습니다. 마음에 들어서 선택을 누르면 매칭(출력)이 성사되고, 다시 다음 카드부터 탐색을 시작합니다.</p>
<h3 id="수식-이해하기">수식 이해하기</h3>
<p>컴퓨터가 &quot;지금 출력을 뱉을까, 말까?&quot;를 결정하는 핵심 수식입니다.</p>
<p>$$p_{i,j} = \sigma(\text{Energy}(s_{i-1}, h_j))$$</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>$p_{i,j}$</td>
<td>지금 쳐다보고 있는 단어에서 스위치를 켤 확률</td>
</tr>
<tr>
<td>$\sigma$ (시그모이드)</td>
<td>어떤 점수든 0~1 사이의 확률값으로 변환하는 함수</td>
</tr>
<tr>
<td>$\text{Energy}$</td>
<td>&#39;지금까지 번역한 상태 $s_{i-1}$&#39;와 &#39;눈앞의 입력 단어 $h_j$&#39;의 궁합 점수</td>
</tr>
</tbody></table>
<p><strong>숫자로 시연해 보면:</strong></p>
<p>모델이 방금 <code>turn on</code>을 뱉어냈고, 지금 <code>light</code>라는 단어를 보고 있습니다. 궁합 점수를 계산해 보니 +2.5점. 이를 시그모이드에 넣으면 약 <strong>0.92</strong>가 나옵니다.</p>
<blockquote>
<p>&quot;92% 확률로 여기서 스위치를 켜고 &#39;조명&#39;이라는 단어를 뱉어야겠다!&quot;</p>
</blockquote>
<p>테스트할 때는 이 값이 0.5를 넘으면 무조건 선택(1)합니다.</p>
<p>이 수식이 없다면, 0과 1로 딱 떨어지는 결정 과정에서 <strong>&#39;미분&#39;이 불가능</strong>해집니다. 미분이 안 되면 딥러닝 모델은 역전파를 통한 학습을 아예 할 수 없습니다.</p>
<hr>
<h3 id="📊-figure-1-어텐션-정렬alignment-방식-비교">📊 Figure 1: 어텐션 정렬(Alignment) 방식 비교</h3>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 입력(가로축)과 출력(세로축)이 어떻게 연결되는지 보여주는 히트맵(바둑판). 밝은 점일수록 모델이 그 입력 단어를 강하게 참고했다는 의미</li>
<li><strong>핵심 메시지:</strong> 기존 소프트 어텐션은 전체 바둑판에 점이 퍼져 있는 반면, 단조 어텐션은 <strong>대각선 아래로 향하는 계단식</strong> 모양을 띱니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>계단 모양은 뒤로 후진하지 않고 앞으로만 나아가며 출력을 만들어낸다는 확실한 시각적 증거입니다. 논문의 핵심 아이디어인 <strong>&#39;직진성(Monotonicity)&#39;</strong> 을 눈으로 바로 납득시켜 줍니다.</p>
</blockquote>
<hr>
<h3 id="📊-figure-2-기대-정렬expected-alignment-계산-흐름도">📊 Figure 2: 기대 정렬(Expected Alignment) 계산 흐름도</h3>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 모델을 훈련할 때, 0 아니면 1로 끊어지는 극단적 결정을 어떻게 부드럽게(Soft) 학습시키는지를 보여주는 화살표 흐름도</li>
<li><strong>핵심 메시지:</strong> 특정 출력 단계에 도달할 수 있는 <strong>&#39;모든 가능한 경로의 확률&#39;</strong> 을 곱하고 더해서 기댓값을 구합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>실전에서는 무식하게 직진(Hard)만 하지만, 훈련할 때는 &quot;혹시 아까 거기서 스위치를 켰다면 어땠을까?&quot; 하는 모든 경우의 수를 부드럽게 계산해줌으로써 오차를 교정하는 구조입니다.</p>
</blockquote>
<hr>
<h2 id="5-experiments--results">5. Experiments &amp; Results</h2>
<p>저자들은 이 모델을 <strong>음성 인식(Speech Recognition)</strong> 과 <strong>기계 번역(Machine Translation)</strong> 두 가지 분야에서 테스트했습니다.</p>
<table>
<thead>
<tr>
<th>태스크</th>
<th>평가 지표</th>
<th>결과</th>
</tr>
</thead>
<tbody><tr>
<td><strong>음성 인식</strong></td>
<td>PER (단어 오류율)</td>
<td>기존 소프트 어텐션과 성능 차이 거의 없음, 속도는 압도적으로 우월</td>
</tr>
<tr>
<td><strong>기계 번역</strong></td>
<td>BLEU (번역 정확도)</td>
<td>어순이 비슷한 언어쌍에서는 준수, 어순 역전이 많은 경우 성능 저하</td>
</tr>
</tbody></table>
<h3 id="결과-해석">결과 해석</h3>
<p>음성 인식의 경우, 소리가 들어오는 순서와 글자가 적히는 순서가 일치하므로(단조성) 이 모델의 강점이 완벽하게 발휘됩니다. 기존의 무거운 소프트 어텐션과 성능은 동등하면서 처리 속도는 압도적으로 빠릅니다.</p>
<blockquote>
<p><strong>결과가 왜 의미 있는가?</strong><br>&quot;입력과 출력의 흐름이 같은 방향일 때&quot;, 이 모델은 기존 무거운 모델을 완벽하게 대체할 수 있는 <strong>실시간 선형 시간 해결책</strong>임을 강력하게 증명했습니다.</p>
</blockquote>
<hr>
<h2 id="6-discussion">6. Discussion</h2>
<h3 id="✅-이-방법의-장점">✅ 이 방법의 장점</h3>
<ol>
<li><strong>진정한 실시간 처리</strong> — 데이터 입력이 끝날 때까지 기다리지 않으므로 스트리밍 환경에 완벽합니다.</li>
<li><strong>메모리 효율 극대화</strong> — 지나간 데이터를 메모리에 계속 들고 있을 필요가 없어 엣지 디바이스에 적합합니다.</li>
<li><strong>훈련 가능한 이산적 선택</strong> — 0과 1의 딱딱한 결정을 기댓값 수식으로 우회하여 딥러닝 프레임워크에서 쉽게 학습할 수 있습니다.</li>
</ol>
<h3 id="❌-한계점">❌ 한계점</h3>
<ol>
<li><strong>어순 변화에 취약</strong> — 한국어↔영어처럼 주어-목적어-동사 순서가 뒤바뀌는 작업에서는 번역 퀄리티가 심각하게 떨어질 수 있습니다. &quot;무조건 직진&quot; 규칙의 치명적 약점입니다.</li>
<li><strong>훈련 시간의 트레이드오프</strong> — 테스트(Inference) 시에는 선형 시간으로 빠르지만, 훈련(Training) 시에는 기댓값을 구하느라 여전히 $O(N^2)$ 복잡도를 가집니다.</li>
</ol>
<h3 id="💡-개선-가능한-방향">💡 개선 가능한 방향</h3>
<p>무조건 앞만 보고 가지 말고, 스위치를 켜기 직전에 뒤쪽 2~3단어 정도는 살짝 다시 쳐다볼 수 있는 <strong>&#39;작은 창(Local Window)&#39;</strong> 개념을 결합한다면 번역 품질 저하를 크게 막을 수 있을 것으로 보입니다.</p>
<hr>
<h2 id="7-my-insights">7. My Insights</h2>
<p>온디바이스 음성 AI 석사 논문을 준비하면서, 저는 늘 모델의 &#39;가중치 크기&#39;를 어떻게 깎아낼까(양자화)에만 매몰되어 있었습니다. 하지만 이 논문을 보며 뒤통수를 한 대 맞은 기분이었습니다.</p>
<blockquote>
<p>모델의 크기를 줄이는 것만큼이나 <strong>&#39;데이터를 읽는 흐름 자체를 최적화하는 것&#39;</strong> 이 엄청난 성능 향상을 가져온다는 사실을 깨달았습니다.</p>
</blockquote>
<p>0과 1의 미분 불가능성(Hard Attention)을 확률의 기댓값이라는 수학적 트릭으로 부드럽게 이어 붙인 저자들의 통찰력이 경이로웠습니다. 반면 훈련 과정에서 모든 경로를 다 더해야 하는 알고리즘 구현 부분은 아직 코드로 직접 짜보지 않아 살짝 헷갈리는 감이 있습니다.</p>
<p>이 인사이트는 현업에서 진행 중인 AWS나 Microsoft Fabric 기반의 실시간 IoT 데이터 파이프라인에도 큰 영감을 줍니다. 스마트 홈 기기(보일러, 매트 등)에서 쏟아지는 방대한 센서 스트리밍 데이터를 처리할 때, 굳이 모든 과거 배치 데이터를 뒤적거리지 않고 현재의 임계값만을 활용해 이상 징후를 즉각(Online) 탐지하는 로직을 설계해 볼 수 있겠다는 아이디어를 얻었습니다.</p>
<hr>
<h2 id="8-summary">8. Summary</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>핵심 문제</strong></td>
<td>기존 어텐션 모델은 데이터를 전부 확인해야만 결과를 내므로 실시간 처리 불가, 연산량 폭발</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>데이터를 한 방향으로만 훑으면서 즉시 출력 여부를 결정하는 <strong>단조 어텐션</strong> 도입</td>
</tr>
<tr>
<td><strong>핵심 기여</strong></td>
<td>어텐션 복잡도를 선형 시간으로 축소, 대기 시간 없는 온라인 스트리밍 처리 구현</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 점</strong></td>
<td>미분 불가능한 Hard Attention을 훈련 시 확률 기댓값으로 우회하는 수학적 트릭</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>무조건 직진만 허용하므로 어순이 다른 언어쌍에서 성능이 크게 떨어짐</td>
</tr>
<tr>
<td><strong>확장 방향</strong></td>
<td>엣지 디바이스용 LLM, 실시간 자율주행 객체 추적, 스트리밍 IoT 센서 이상 탐지 아키텍처</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>단조 어텐션은 &quot;무조건 앞으로만 직진&quot;이라는 단순한 규칙 하나로, AI가 스트리밍 데이터를 실시간·저비용으로 처리할 수 있게 만든 우아한 해결책이다.</strong></p>
</blockquote>
<hr>
<p>혹시 해당 논문 내용 중 제가 이해한 부분이 잘못된 부분이 있으면 언제든지 피드백 부탁드리겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Attention Is All You Need]]></title>
            <link>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Attention-Is-All-You-Need</link>
            <guid>https://velog.io/@dev_brojean/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Attention-Is-All-You-Need</guid>
            <pubDate>Thu, 26 Feb 2026 14:16:24 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>현대 AI의 뼈대가 된 2017년 구글의 전설적인 논문을 뜯어봅니다.<br><strong>핵심 한 줄:</strong> 단어를 줄 세워 읽던 관행을 박살내고, 모든 단어의 얽힌 관계를 동시에 계산한 혁명적 아키텍처.</p>
</blockquote>
<hr>
<h2 id="1-왜-이-논문을-읽게-되었는가">1. 왜 이 논문을 읽게 되었는가</h2>
<p>최근 업무에서 RAG(검색 증강 생성) 시스템의 검색 성능을 높이는 작업을 하고 있습니다. 또한 다양한 거대 언어 모델(LLM)을 활용해 프롬프트를 최적화하는 일도 병행하고 있습니다.</p>
<p>이 과정에서 항상 비슷한 벽에 부딪혔습니다.</p>
<blockquote>
<p>&quot;왜 모델은 입력 길이가 길어지면 앞부분의 지시사항을 잊어버릴까?&quot;<br>&quot;문맥(Context)을 도대체 어떤 원리로 이해하는 걸까?&quot;</p>
</blockquote>
<p>이런 고민을 해결하려면 모델이 텍스트를 처리하는 근본적인 원리를 알아야 했습니다. 그래서 현재 우리가 사용하는 거의 모든 최신 AI의 뿌리가 되는 전설적인 논문, 2017년 구글의 <strong>&quot;Attention Is All You Need&quot;</strong> 를 다시 펼쳤습니다.</p>
<p>겉보기에는 복잡한 수식이 가득한 학술 논문입니다. 하지만 그 원리를 하나씩 뜯어보니 놀랍도록 직관적이었습니다. 오늘은 제가 이 논문을 공부하며 깨달은 점들을 여러분과 함께 나누고자 합니다.</p>
<hr>
<h2 id="2-이-논문이-해결하려는-문제">2. 이 논문이 해결하려는 문제</h2>
<p>이 논문이 나오기 전인 2017년 이전의 상황을 먼저 알아야 합니다. 당시 자연어 처리(NLP) 분야는 <strong>순환 신경망(RNN)</strong> 이라는 기술이 지배하고 있었습니다.</p>
<h3 id="기존-방법의-한계">기존 방법의 한계</h3>
<p>RNN의 가장 큰 특징은 단어를 <strong>&#39;순서대로&#39;</strong> 읽는다는 것입니다. &quot;나는&quot;, &quot;오늘&quot;, &quot;밥을&quot;, &quot;먹었다&quot;라는 문장이 있으면 앞에서부터 차례대로 하나씩 입력했습니다.</p>
<p>이 방식에는 치명적인 단점이 두 가지 있었습니다.</p>
<table>
<thead>
<tr>
<th>한계</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>장기 기억 상실</strong> (Long-term dependency)</td>
<td>문장이 조금만 길어지면 앞부분의 정보를 잊어버림</td>
</tr>
<tr>
<td><strong>느린 속도</strong></td>
<td>단어를 하나씩 순서대로 처리해야 하므로 컴퓨터의 &#39;동시 계산(병렬 처리)&#39;을 활용할 수 없음</td>
</tr>
</tbody></table>
<h3 id="왜-이-문제가-중요한가">왜 이 문제가 중요한가</h3>
<p>대규모 데이터를 학습하려면 처리 속도가 생명입니다. 위키백과 전체를 학습시키려면 RNN 방식으로는 몇 년이 걸릴 수도 있습니다.</p>
<h3 id="실제-사례">실제 사례</h3>
<pre><code>&quot;The animal didn&#39;t cross the street because it was too tired.&quot;</code></pre><p>여기서 <code>it</code>은 동물일까요, 길일까요? 사람은 문맥을 보고 &#39;동물&#39;이라는 것을 바로 압니다. 하지만 옛날 AI는 문장 끝에 도달할 때쯤이면 문장 맨 앞의 <code>animal</code>이라는 단어와의 연결고리가 희미해져서 번역을 망치곤 했습니다.</p>
<hr>
<h2 id="3-핵심-아이디어-직관적으로-설명">3. 핵심 아이디어 (직관적으로 설명)</h2>
<p>저자들은 아주 과감하고 단순한 아이디어를 던집니다.</p>
<blockquote>
<p><strong>핵심 한 문장</strong><br>&quot;단어를 순서대로 읽는 방식을 완전히 버리자. 대신 모든 단어들 사이의 &#39;관계성&#39;을 <strong>동시에</strong> 계산하는 어텐션(Attention) 기술만으로 문장을 이해하자.&quot;</p>
</blockquote>
<h3 id="비유-1-칵테일-파티-효과-🎉">비유 1: 칵테일 파티 효과 🎉</h3>
<p>시끄러운 파티장을 상상해 보세요. 음악 소리와 사람들의 대화 소리가 뒤섞여 있습니다. 하지만 누군가 내 이름을 부르면 그 소리만 선명하게 들립니다.</p>
<p>트랜스포머의 &#39;어텐션&#39;도 이와 같습니다. 수십 개의 단어가 쏟아져 들어와도, <strong>지금 당장 집중해야 할 핵심 단어에만 강하게 귀를 기울입니다.</strong></p>
<h3 id="비유-2-수사관의-단서-연결망-🔍">비유 2: 수사관의 단서 연결망 🔍</h3>
<p>영화에 나오는 수사관의 칠판을 떠올려 보세요. 범행 현장 사진, 흉기, 용의자 이름이 여기저기 붙어 있습니다. 수사관은 이것들을 순서대로 읽지 않습니다. 대신 관련 있는 것들끼리 <strong>&#39;붉은 실&#39;로 연결</strong>합니다.</p>
<p>트랜스포머는 문장 안의 모든 단어를 한 번에 칠판에 펼쳐놓고, 서로 연관 깊은 단어들끼리 굵은 선으로 연결합니다.</p>
<h3 id="실제-상황-예시">실제 상황 예시</h3>
<pre><code>&quot;배를 먹으면서 배를 탔다.&quot;</code></pre><p>이 문장을 AI가 처리합니다. 순서대로 읽지 않습니다. <strong>모든 단어를 동시에</strong> 봅니다.</p>
<ul>
<li>첫 번째 &#39;배&#39; → <strong>&#39;먹으면서&#39;</strong> 와 강한 선으로 연결 (과일)</li>
<li>두 번째 &#39;배&#39; → <strong>&#39;탔다&#39;</strong> 와 강한 선으로 연결 (선박)</li>
</ul>
<p>이렇게 동시에 문맥을 파악하여 두 단어의 뜻이 다르다는 것을 단번에 알아냅니다.</p>
<hr>
<h2 id="4-수식-쉽게-이해하기">4. 수식 쉽게 이해하기</h2>
<p>논문에서 가장 유명하고 중요한 핵심 수식입니다.</p>
<p>$$Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$</p>
<p>알파벳이 복잡해 보이지만, <strong>도서관 검색 시스템</strong>으로 비유하면 아주 쉽습니다.</p>
<table>
<thead>
<tr>
<th>기호</th>
<th>도서관 비유</th>
<th>실제 의미</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Q</strong> (Query)</td>
<td>검색창에 치는 <strong>검색어</strong></td>
<td>내가 현재 집중하는 단어</td>
</tr>
<tr>
<td><strong>K</strong> (Key)</td>
<td>도서관 책들의 <strong>제목</strong></td>
<td>문장 안의 다른 모든 단어들</td>
</tr>
<tr>
<td><strong>V</strong> (Value)</td>
<td>책들의 실제 <strong>내용</strong></td>
<td>단어들이 가진 고유한 의미</td>
</tr>
<tr>
<td><strong>$\sqrt{d_k}$</strong></td>
<td><strong>안전장치(브레이크)</strong></td>
<td>숫자가 폭발적으로 커지는 것을 방지</td>
</tr>
<tr>
<td><strong>softmax</strong></td>
<td><strong>비율 변환기</strong></td>
<td>점수들을 합쳐서 100% 비율로 만들어주는 함수</td>
</tr>
</tbody></table>
<h3 id="숫자-예시로-계산-과정-시연">숫자 예시로 계산 과정 시연</h3>
<pre><code>Q (나의 질문)  = [1, 0]  → &#39;강아지&#39;
K1 (다른 단어) = [1, 0]  → &#39;멍멍이&#39;
K2 (다른 단어) = [0, 1]  → &#39;자동차&#39;</code></pre><ol>
<li><strong>내적 계산:</strong> Q·K1 = <strong>100점</strong> (완전히 닮음), Q·K2 = <strong>0점</strong> (완전히 다름)</li>
<li><strong>softmax 적용:</strong> K1 → <strong>73%</strong>, K2 → <strong>27%</strong></li>
<li><strong>최종 결합:</strong> K1의 의미를 73%만큼, K2의 의미를 27%만큼 가져와 하나로 섞어줌</li>
</ol>
<blockquote>
<p><strong>이 수식의 직관적 재해석</strong><br>이 수식은 결국 <strong>&quot;문맥 믹서기&quot;</strong> 입니다.<br>현재 단어에 주변 단어들의 의미를 &#39;닮은 정도&#39;에 비례하여 적절히 섞어주는 역할을 합니다.</p>
</blockquote>
<p><strong>이 수식이 없다면?</strong> 문장 안의 단어들은 서로 철저히 고립됩니다. &quot;Apple&quot; 옆에 &quot;Steve Jobs&quot;가 있든 &quot;Banana&quot;가 있든, AI는 문맥을 전혀 파악하지 못하게 됩니다.</p>
<hr>
<h2 id="5-논문-figure-해석">5. 논문 Figure 해석</h2>
<h3 id="📊-figure-1-모델-아키텍처-the-transformer---model-architecture">📊 Figure 1: 모델 아키텍처 (The Transformer - model architecture)</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/8dc46816-0fea-47d0-ab1e-3120bbdd121c/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 트랜스포머 모델의 전체 구조도. 왼쪽 회색 박스는 <strong>인코더(Encoder)</strong>, 오른쪽 회색 박스는 <strong>디코더(Decoder)</strong></li>
<li><strong>실험 설정:</strong> 왼쪽·오른쪽 박스가 각각 <strong>6번씩(Nx=6)</strong> 햄버거 패티처럼 위로 겹겹이 쌓임</li>
<li><strong>핵심 메시지:</strong> 기존에 필수로 쓰이던 RNN이나 CNN이 완전히 사라졌습니다. 오직 <strong>Multi-Head Attention</strong> 블록만 존재합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>거대한 공장 컨베이어 벨트 같습니다. 왼쪽 인코더 공장에서는 외국어 문장을 씹고 뜯어 완벽한 &#39;의미 덩어리&#39;로 압축합니다. 오른쪽 디코더 공장은 이 덩어리 도면을 보고 번역된 한국어 단어를 하나씩 조립해냅니다.</p>
</blockquote>
<ul>
<li><strong>이 그림이 중요한 이유:</strong> 단순한 구조(Attention + Feed Forward)만으로 언어 번역이 가능하다는 것을 시각적으로 증명합니다.</li>
<li><strong>한계점:</strong> 블록이 하나만 그려져 있어 초보자는 층이 여러 개 쌓여있다는 사실(Nx)을 간과하기 쉽습니다.</li>
</ul>
<hr>
<h3 id="📊-figure-2-왼쪽-스케일드-닷-프로덕트-어텐션-scaled-dot-product-attention">📊 Figure 2 (왼쪽): 스케일드 닷-프로덕트 어텐션 (Scaled Dot-Product Attention)</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/e853cffa-aa0d-4077-af37-b20230800f8e/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> Q, K, V 수식이 컴퓨터 내부에서 계산되는 순서도</li>
<li><strong>연산 순서:</strong> <code>MatMul → Scale → Mask(옵션) → Softmax → MatMul</code></li>
<li><strong>핵심 메시지:</strong> 단어 간의 관계 파악이라는 복잡한 작업을 단순한 <strong>&#39;행렬 곱셈&#39;</strong> 으로 치환했습니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>행렬 곱셈은 GPU가 세상에서 가장 잘하는 일입니다. 트랜스포머가 기존 모델보다 압도적으로 빠르게 학습할 수 있는 비밀이 바로 이 단순한 행렬 곱셈 구조에 있었습니다.</p>
</blockquote>
<ul>
<li><strong>한계점:</strong> 중간의 <code>Mask(옵션)</code> 기능이 헷갈릴 수 있습니다. 이는 디코더에서 &#39;미래의 단어를 미리 컨닝하지 못하게&#39; 가려버리는 역할입니다.</li>
</ul>
<hr>
<h3 id="📊-figure-3-오른쪽-멀티-헤드-어텐션-multi-head-attention">📊 Figure 3 (오른쪽): 멀티 헤드 어텐션 (Multi-Head Attention)</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/5169e3c0-2556-439b-8a28-45e0b806f56a/image.png" alt=""></p>
<ul>
<li><strong>이 그림이 보여주는 것:</strong> 어텐션 연산을 한 번만 크게 하는 것이 아니라, <strong>여러 개(논문에서는 8개)로 잘게 쪼개어 동시에</strong> 수행하는 구조</li>
<li><strong>연산 순서:</strong> <code>Linear(8개로 분할) → 각 Head별 Attention → Concat → Linear</code></li>
<li><strong>핵심 메시지:</strong> 문장을 하나의 시야로만 보면 중요한 정보를 놓칠 수 있습니다. 다각도로 분석해야 합니다.</li>
</ul>
<blockquote>
<p><strong>내가 이해한 포인트</strong><br>8명의 전문가가 모인 조별 과제와 같습니다.<br>1번 전문가는 &#39;문법&#39;만, 2번은 &#39;감정&#39;만, 3번은 &#39;인물 관계&#39;만 분석합니다.<br>마지막에 각자의 보고서를 하나로 합치면 문장에 대한 완벽한 이해가 완성됩니다.</p>
</blockquote>
<ul>
<li><strong>이 그림이 중요한 이유:</strong> 모델이 문맥을 풍부하게 포착하여 번역 성능을 끌어올릴 수 있었던 이유를 설명합니다.</li>
<li><strong>한계점:</strong> AI가 스스로 8개의 머리마다 각기 다른 역할을 부여하도록 학습되지만, 구체적으로 어떤 머리가 어떤 역할을 하는지 사람이 완벽히 통제하기는 어렵습니다. <strong>(블랙박스 문제)</strong></li>
</ul>
<hr>
<h2 id="6-실험-결과-분석">6. 실험 결과 분석</h2>
<h3 id="무엇을-증명했는가">무엇을 증명했는가</h3>
<p>저자들은 영어-독일어 번역과 영어-프랑스어 번역 대회(WMT 2014) 데이터를 사용하여, 기존의 모든 AI 모델을 꺾고 <strong>최고 성능(SOTA)</strong> 을 달성했습니다.</p>
<h3 id="결과가-설득력-있는-이유">결과가 설득력 있는 이유</h3>
<p>번역 품질 지표인 <strong>BLEU 점수</strong>에서 압도적인 1등을 차지했습니다. 더욱 놀라운 것은 기존 최고 모델들의 연산량 중 아주 적은 일부만 사용하고도 이 결과를 냈다는 점입니다.</p>
<blockquote>
<p><strong>성능은 올리고 비용은 깎아버린 완벽한 증명이었습니다.</strong></p>
</blockquote>
<h3 id="통계적-신뢰성">통계적 신뢰성</h3>
<p>학계 표준 데이터셋을 사용하고, <strong>Base 모델</strong>과 <strong>Big 모델</strong> 두 가지 버전을 모두 실험하여 일관된 성능 향상을 보여주었으므로 신뢰성이 매우 높습니다.</p>
<h3 id="다른-해석-가능성">다른 해석 가능성</h3>
<blockquote>
<p>&quot;단순히 파라미터(모델 크기)가 커져서 똑똑해진 것 아니야?&quot;</p>
</blockquote>
<p>이에 대해 저자들은 모델 크기가 작은 <strong>Base 버전으로도 과거의 무거운 모델들을 이겼습니다.</strong> 구조 자체가 우월하다는 것을 입증한 것입니다.</p>
<hr>
<h2 id="7-비판적-관점">7. 비판적 관점</h2>
<h3 id="✅-강점">✅ 강점</h3>
<ol>
<li>압도적인 학습 속도 — 병렬 처리의 극대화</li>
<li>문장이 아무리 길어도 첫 단어와 끝 단어의 관계를 잃지 않음</li>
<li>모델 크기를 키우고 데이터를 많이 넣을수록 성능이 계속 우상향 <strong>(확장성)</strong></li>
<li>어텐션 점수를 시각화하여 AI가 어디를 보는지 해석 가능</li>
<li>언어뿐만 아니라 이미지, 소리 등 모든 순차적 데이터에 적용 가능한 <strong>범용성</strong></li>
</ol>
<h3 id="❌-한계">❌ 한계</h3>
<ol>
<li><strong>$N^2$ 메모리 문제:</strong> 문장이 길어지면 계산량이 길이의 제곱으로 폭발</li>
<li>기본적인 데이터 규칙을 몰라서 무식하게 많은 데이터를 먹여야만 똑똑해짐</li>
<li>위치 인코딩을 함수로 억지로 넣다 보니 아주 긴 문장에서는 길을 잃음</li>
<li>번역 결과를 내뱉을 때는 여전히 한 단어씩 순서대로 뱉어야 해서 <strong>추론이 느림</strong></li>
<li>문맥 전체를 훑느라 바로 옆 단어와의 끈끈한 결속력을 가끔 무시함</li>
</ol>
<h3 id="실제-적용-시-문제">실제 적용 시 문제</h3>
<p>실제 RAG 시스템을 구축할 때 직면하는 가장 큰 문제가 바로 <strong>한계 1번($N^2$ 문제)</strong> 입니다. 모델에 참고할 문서를 많이 넣어주면(Context Length 증가), 연산량이 제곱으로 폭발해 API 비용이 치솟고 응답이 심각하게 느려집니다. 온디바이스 AI처럼 메모리가 적은 기기에는 이 무거운 트랜스포머를 그대로 올리기가 불가능에 가깝습니다.</p>
<h3 id="개선-가능성">개선 가능성</h3>
<p>최근에는 이 메모리 문제를 해결하기 위해 중요하지 않은 단어는 계산에서 빼버리는 <strong>Sparse Attention</strong>이나, 하드웨어 연산을 최적화한 <strong>FlashAttention</strong> 기술들이 나오며 한계를 극복해 나가고 있습니다.</p>
<hr>
<h2 id="8-내가-얻은-인사이트">8. 내가 얻은 인사이트</h2>
<h3 id="새롭게-알게-된-점">새롭게 알게 된 점</h3>
<p>AI가 글을 이해하는 방식이 마법이 아니라는 것을 알았습니다. 철저하게 <strong>단어와 단어 사이의 유사도를 행렬 곱셈으로 구하고, 그 점수만큼 의미를 더하는 수학적 과정</strong>이었습니다.</p>
<h3 id="기존-생각이-바뀐-부분">기존 생각이 바뀐 부분</h3>
<p>글은 항상 왼쪽에서 오른쪽으로, 순서대로 읽어야 한다고 생각했습니다.</p>
<p>하지만 트랜스포머는 텍스트를 순서가 있는 <strong>선(Line)</strong> 이 아니라, 모든 단어가 서로 연결된 촘촘한 <strong>그물망(Graph)</strong> 으로 바라봤습니다.</p>
<blockquote>
<p>관점의 전환이 얼마나 파괴적인 혁신을 가져오는지 깨달았습니다.</p>
</blockquote>
<hr>
<h2 id="9-한눈에-정리">9. 한눈에 정리</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td><strong>문제</strong></td>
<td>기존 RNN은 단어를 순서대로 처리하느라 너무 느리고 긴 문장을 잘 까먹었다</td>
</tr>
<tr>
<td><strong>해결 방법</strong></td>
<td>순서대로 읽는 방식을 버리고, 모든 단어의 관계를 한 번에 계산하는 &#39;Self-Attention&#39; 도입</td>
</tr>
<tr>
<td><strong>가장 중요한 기여</strong></td>
<td>현대 LLM(ChatGPT, Gemini 등)의 뼈대가 되는 <strong>트랜스포머(Transformer) 아키텍처</strong> 최초 제안</td>
</tr>
<tr>
<td><strong>가장 인상 깊었던 부분</strong></td>
<td>복잡한 언어의 문맥 파악을 단순한 행렬 곱셈($QK^T$)으로 우아하게 풀어낸 발상의 전환</td>
</tr>
<tr>
<td><strong>아쉬운 점</strong></td>
<td>입력 길이가 길어지면 메모리 사용량이 제곱으로 폭발 — 현재 LLM 컨텍스트 윈도우 한계의 원흉</td>
</tr>
</tbody></table>
<hr>
<blockquote>
<h3 id="🧠-이-논문을-한-문장으로-말하면">🧠 이 논문을 한 문장으로 말하면?</h3>
<p><strong>트랜스포머는 단어를 줄 세워 읽던 관행을 박살내고, 모든 단어의 얽힌 관계를 동시에 계산하여 AI의 폭발적 진화를 이끈 혁명적인 아키텍처다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration]]></title>
            <link>https://velog.io/@dev_brojean/AWQ-Activation-aware-Weight-Quantization-for-LLM-Compression-and-Acceleration</link>
            <guid>https://velog.io/@dev_brojean/AWQ-Activation-aware-Weight-Quantization-for-LLM-Compression-and-Acceleration</guid>
            <pubDate>Sat, 22 Nov 2025 06:52:36 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-awq-activation-aware-weight-quantization-for-on-device-llm-compression-and-acceleration">📝 AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration</h1>
<hr>
<p><strong>한 줄 요약:</strong><br>대규모 언어 모델(LLM)의 가중치를 4비트로 양자화할 때, 활성화(activation) 분포에 기반하여 중요한 가중치 채널을 보호함으로써 정확도 손실 없이 3배 이상의 추론 속도 향상을 달성한 연구.</p>
<hr>
<h2 id="1-서론-및-연구-배경-introduction">1. 서론 및 연구 배경 (Introduction)</h2>
<h3 id="연구의-필요성-기존-연구의-한계점">연구의 필요성: 기존 연구의 한계점</h3>
<p>대규모 언어 모델(LLM)은 챗봇, 가상 비서, 자율주행차 등 다양한 분야에서 혁신을 가져왔지만, <strong>천문학적인 모델 크기</strong>가 온디바이스 배포의 최대 걸림돌이었습니다. 예를 들어:</p>
<ul>
<li>GPT-3는 175B 파라미터로 FP16 기준 <strong>350GB</strong>의 메모리를 요구</li>
<li>최신 B200 GPU도 192GB 메모리에 불과하여, 엣지 디바이스는 말할 것도 없음</li>
<li>기존 양자화 방법(GPTQ 등)은 <strong>보정(calibration) 데이터셋에 과적합</strong>되어, 범용성이 떨어짐</li>
</ul>
<p>특히 Post-Training Quantization(PTQ) 방식의 기존 연구들은 다음 문제를 겪었습니다:</p>
<ol>
<li><strong>GPTQ</strong>: 2차 정보를 활용한 오류 보정(error compensation)을 수행하지만, 재구성(reconstruction) 과정에서 보정 데이터에 과적합되어 <strong>도메인 외(out-of-distribution) 성능이 저하</strong></li>
<li><strong>Round-to-Nearest(RTN)</strong>: 단순 반올림 방식으로 INT3/INT4 저비트에서 <strong>성능 급락</strong></li>
</ol>
<h3 id="연구-목표-새로운-접근법의-필요성">연구 목표: 새로운 접근법의 필요성</h3>
<p>저자들은 다음과 같은 핵심 통찰(insight)에서 출발했습니다:</p>
<blockquote>
<p><strong>&quot;LLM의 모든 가중치가 동등하게 중요하지 않다. 소수(0.1~1%)의 핵심(salient) 가중치만 보호해도 양자화 오류를 크게 줄일 수 있다.&quot;</strong></p>
</blockquote>
<p>그러나 중요한 가중치를 <strong>혼합 정밀도(mixed-precision)</strong>로 유지하면 하드웨어 구현이 비효율적</p>
<ul>
<li><strong>활성화 분포(activation distribution)</strong>를 기반으로 중요 채널을 식별</li>
<li><strong>채널별 스케일링(per-channel scaling)</strong>으로 중요 가중치를 보호하되, <strong>전체를 동일 비트로 유지</strong>(하드웨어 친화적)</li>
<li>역전파나 재구성 없이 작동하여 <strong>일반화 성능 우수</strong></li>
</ul>
<hr>
<h2 id="2-제안-방법론-methodology---매우-상세하게">2. 제안 방법론 (Methodology) - 매우 상세하게</h2>
<h3 id="핵심-아이디어-활성화-인지activation-aware-양자화">핵심 아이디어: 활성화 인지(Activation-aware) 양자화</h3>
<p>AWQ의 핵심은 <strong>&quot;가중치의 중요도는 가중치 자체의 크기가 아닌, 해당 채널을 통과하는 활성화의 크기에 의해 결정된다&quot;</strong>는 원리</p>
<h4 id="1단계-중요-가중치-채널-식별">1단계: 중요 가중치 채널 식별</h4>
<p>논문의 <strong>Table 1</strong> 실험 결과를 보면:</p>
<table>
<thead>
<tr>
<th>모델</th>
<th>RTN (w3-g128)</th>
<th>활성화 기반 1% FP16</th>
<th>가중치 기반 1% FP16</th>
<th>랜덤 1% FP16</th>
</tr>
</thead>
<tbody><tr>
<td>OPT-6.7B</td>
<td>23.54 PPL</td>
<td><strong>11.39 PPL</strong></td>
<td>22.37 PPL</td>
<td>23.54 PPL</td>
</tr>
</tbody></table>
<ul>
<li><strong>활성화 분포 기반</strong>으로 선택된 1%의 채널만 FP16으로 유지했을 때, Perplexity가 23.54 → 11.39로 <strong>급감</strong> (성능 대폭 개선)</li>
<li>반면 가중치 크기(L2-norm) 기반 선택이나 랜덤 선택은 거의 효과 없음</li>
</ul>
<p><strong>해석:</strong> 활성화 값이 큰 채널은 더 중요한 특징(feature)을 처리하므로, 해당 가중치를 정밀하게 유지</p>
<h4 id="2단계-스케일링을-통한-양자화-오류-감소">2단계: 스케일링을 통한 양자화 오류 감소</h4>
<p>혼합 정밀도는 하드웨어 구현이 복잡하므로, AWQ는 <strong>수학적으로 동등한 변환(equivalent transformation)</strong>을 활용</p>
<p><strong>양자화 함수:</strong></p>
<pre><code>Q(w) = Δ · Round(w/Δ), 여기서 Δ = max(|w|) / (2^(N-1))</code></pre><p>(N: 양자화 비트 수, Δ: 스케일러)</p>
<p>특정 가중치 w를 s배(s&gt;1) 스케일업하고, 입력 활성화 x를 1/s로 스케일다운하면:</p>
<pre><code>Q(w·s) · (x/s) = Δ&#39; · Round(ws/Δ&#39;) · x · (1/s)</code></pre><p><strong>핵심 발견 (Table 2 실험):</strong></p>
<table>
<thead>
<tr>
<th>s 값</th>
<th>Δ 변화 비율</th>
<th>평균 오류 감소율</th>
<th>Wiki-2 PPL</th>
</tr>
</thead>
<tbody><tr>
<td>1.0</td>
<td>0%</td>
<td>1.0</td>
<td>23.54</td>
</tr>
<tr>
<td>2.0</td>
<td>8.2%</td>
<td><strong>0.519</strong></td>
<td><strong>11.92</strong></td>
</tr>
<tr>
<td>4.0</td>
<td>21.2%</td>
<td>0.303</td>
<td>12.36</td>
</tr>
</tbody></table>
<ul>
<li>s=2일 때, 중요 채널의 <strong>상대 양자화 오류가 약 절반</strong>으로 감소</li>
<li>s가 너무 크면(s=4) 비중요 채널의 Δ가 증가하여 오히려 성능 저하</li>
</ul>
<p><strong>직관적 이해:</strong><br>중요한 가중치를 크게 만들면(s배), 양자화 스텝(Δ)은 거의 변하지 않지만, 반올림 오차는 상대적으로 작아집니다. 마치 작은 물체를 확대한 후 디지털화하면 디테일이 더 잘 보존되는 원리와 유사</p>
<h3 id="step-by-step-프로세스">Step-by-Step 프로세스</h3>
<pre><code>1. 보정 데이터셋(calibration set)에서 각 채널별 활성화 평균 크기(sₓ) 측정
2. 최적 스케일 s = sₓ^α 형태로 탐색 공간 설정
3. α ∈ [0, 1] 범위에서 그리드 서치(20단계)로 최적 α 찾기
   - 목표: ||Q(W·diag(s))·(diag(s)⁻¹·X) - WX|| 최소화
4. 찾아진 스케일로 가중치 변환 후 양자화
5. 추론 시 s⁻¹·X는 이전 레이어 연산에 융합(fuse) 가능</code></pre><p><strong>장점:</strong></p>
<ul>
<li>역전파 불필요 → 연산 효율적</li>
<li>보정 데이터 의존도 낮음 → 일반화 우수</li>
<li>하드웨어 친화적 (단일 정밀도 유지)</li>
</ul>
<hr>
<h2 id="3-주요-실험-결과-experiments--results">3. 주요 실험 결과 (Experiments &amp; Results)</h2>
<h3 id="llamallama-2-모델-성능-비교">LLaMA/Llama-2 모델 성능 비교</h3>
<p>논문의 핵심 결과 테이블:</p>
<table>
<thead>
<tr>
<th>모델 크기</th>
<th>FP16</th>
<th>RTN (INT3)</th>
<th>GPTQ</th>
<th>GPTQ-R</th>
<th><strong>AWQ</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Llama-2 7B</td>
<td>5.47</td>
<td>6.66</td>
<td>6.43</td>
<td>6.42</td>
<td><strong>6.24</strong></td>
</tr>
<tr>
<td>Llama-2 70B</td>
<td>3.32</td>
<td>3.98</td>
<td>3.88</td>
<td>3.86</td>
<td><strong>3.74</strong></td>
</tr>
<tr>
<td>LLaMA 7B</td>
<td>5.68</td>
<td>7.01</td>
<td>8.81</td>
<td>6.53</td>
<td><strong>6.35</strong></td>
</tr>
</tbody></table>
<p><strong>시각적 내용 (WikiText-2 Perplexity, 낮을수록 좋음):</strong></p>
<ul>
<li>X축: 모델 크기 (7B ~ 70B)</li>
<li>Y축: Perplexity 수치</li>
<li>AWQ(주황선)가 모든 모델에서 RTN, GPTQ보다 일관되게 낮은 PPL 달성</li>
</ul>
<p><strong>해석:</strong></p>
<ol>
<li><strong>INT3 양자화</strong>에서 AWQ는 RTN 대비 7B 모델에서 6.66→6.24 (6.3% 개선), GPTQ보다도 우수</li>
<li>특히 <strong>LLaMA 7B에서 GPTQ는 8.81</strong>로 실패했으나, AWQ는 6.35로 안정적</li>
<li><strong>70B 초대형 모델</strong>에서도 FP16 3.32 대비 AWQ는 3.74로 손실 최소화</li>
</ol>
<h3 id="instruction-tuned-모델vicuna-gpt-4-평가">Instruction-tuned 모델(Vicuna) GPT-4 평가</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/fbccf372-cc3d-4d1d-9d63-a76922646e5d/image.png" alt=""></p>
<p><strong>시각적 내용:</strong>  </p>
<ul>
<li>80개 샘플 질문에 대해 양자화 모델 vs FP16 응답을 GPT-4가 평가</li>
<li>파란색(Quantized Win): 양자화 모델이 더 좋은 답변</li>
<li>회색(Tie): 동등</li>
<li>빨간색(Quantized Lost): 양자화 모델이 나쁜 답변</li>
</ul>
<table>
<thead>
<tr>
<th>모델</th>
<th>RTN Win</th>
<th>GPTQ Win</th>
<th><strong>AWQ Win</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Vicuna-7B</td>
<td>52</td>
<td>71</td>
<td><strong>75</strong></td>
</tr>
<tr>
<td>Vicuna-13B</td>
<td>47</td>
<td>57</td>
<td><strong>57</strong> (동률 최고)</td>
</tr>
</tbody></table>
<p><strong>해석:</strong><br>AWQ는 instruction-tuned 모델에서도 <strong>가장 많은 승리 케이스</strong>를 기록하여, 일반화 능력이 뛰어남을 입증</p>
<h3 id="멀티모달-모델-openflamingo-9b-coco-captioning">멀티모달 모델 OpenFlamingo-9B (COCO Captioning)</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/f194592f-5f5c-4a0a-96aa-7dd824be8a81/image.png" alt=""></p>
<table>
<thead>
<tr>
<th>Few-shot</th>
<th>FP16</th>
<th>RTN (INT4)</th>
<th>GPTQ</th>
<th><strong>AWQ</strong></th>
</tr>
</thead>
<tbody><tr>
<td>32-shot</td>
<td>81.70 CIDEr</td>
<td>77.13 (-4.57)</td>
<td>74.98 (-6.72)</td>
<td><strong>80.53 (-1.17)</strong></td>
</tr>
<tr>
<td>0-shot</td>
<td>63.73</td>
<td>60.24</td>
<td>59.72</td>
<td><strong>62.57</strong></td>
</tr>
</tbody></table>
<p><strong>시각적 내용:</strong><br>그래프에서 AWQ(주황선)는 모든 few-shot 설정(0/4/8/16/32-shot)에서 RTN, GPTQ보다 FP16에 근접</p>
<p><strong>해석:</strong>  </p>
<ul>
<li><strong>멀티모달 LLM의 첫 저비트 양자화 성공 사례</strong></li>
<li>32-shot에서 AWQ는 FP16 대비 단 1.17 CIDEr 감소로, <strong>거의 무손실</strong> 수준</li>
<li>GPTQ는 6.72 하락하여 과적합 문제 노출</li>
</ul>
<h3 id="병목-현상-분석-rtx-4090-gpu">병목 현상 분석 (RTX 4090 GPU)</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/d4e47f11-55bb-474f-b664-a47d0a7d7a2a/image.png" alt=""></p>
<p><strong>왼쪽 그래프: Context vs Generation 시간</strong></p>
<ul>
<li>Context 단계(200 토큰): 10ms</li>
<li>Generation 단계(20 토큰): <strong>310ms</strong> → 생성 단계가 31배 느림</li>
</ul>
<p><strong>중간 그래프: Roofline 분석</strong></p>
<ul>
<li>Y축: Peak TFLOPS (최대 165)</li>
<li>X축: Arithmetic Intensity (연산/메모리 비율)</li>
<li>FP16 Generation: <strong>Intensity=1</strong> → 메모리 바운드</li>
<li>AWQ W4A16: <strong>Intensity=4</strong> → 4배 개선으로 4 TFLOPS 달성 가능</li>
</ul>
<p><strong>오른쪽 그래프: 메모리 접근 비중</strong></p>
<ul>
<li>Weight 접근: <strong>134MB</strong> (압도적)</li>
<li>Activation 접근: <strong>1.7MB</strong></li>
<li>가중치 접근이 79배 많음 → 가중치 압축이 핵심</li>
</ul>
<p><strong>해석:</strong><br>온디바이스 LLM은 <strong>메모리 대역폭(memory bandwidth)</strong>에 의해 성능이 제한됩니다. AWQ는 가중치를 4비트로 압축하여 이론상 4배 메모리 절감 → 실제 3배 이상 속도 향상 가능.</p>
<h3 id="tinychat-시스템-실측-성능">TinyChat 시스템 실측 성능</h3>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/a46d2398-b70c-4f8c-8e2c-e218fd1f0519/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_brojean/post/39c5396c-f66b-4ac3-baef-3f11bdfb7885/image.png" alt=""></p>
<p><strong>RTX 4090 Desktop GPU:</strong></p>
<table>
<thead>
<tr>
<th>모델</th>
<th>Huggingface FP16</th>
<th>TinyChat FP16</th>
<th>TinyChat AWQ (W4A16)</th>
</tr>
</thead>
<tbody><tr>
<td>Llama-2-7B</td>
<td>52 tok/s</td>
<td>62 tok/s</td>
<td><strong>194 tok/s</strong></td>
</tr>
<tr>
<td>Llama-2-13B</td>
<td>49 tok/s</td>
<td>-</td>
<td><strong>158 tok/s</strong></td>
</tr>
<tr>
<td>Falcon-7B</td>
<td>124 tok/s</td>
<td>-</td>
<td><strong>194 tok/s</strong></td>
</tr>
</tbody></table>
<p><strong>Jetson Orin Mobile GPU:</strong></p>
<table>
<thead>
<tr>
<th>모델</th>
<th>Huggingface FP16</th>
<th>TinyChat AWQ</th>
</tr>
</thead>
<tbody><tr>
<td>Llama-2-7B</td>
<td>22 tok/s</td>
<td><strong>38 tok/s</strong></td>
</tr>
<tr>
<td>Llama-2-13B</td>
<td>OOM</td>
<td><strong>21 tok/s</strong></td>
</tr>
</tbody></table>
<p><strong>해석:</strong></p>
<ol>
<li><strong>Desktop GPU</strong>: AWQ+TinyChat은 Huggingface FP16 대비 <strong>3.1~3.9배</strong> 속도 향상</li>
<li><strong>Mobile GPU</strong>: 13B 모델이 FP16에서는 메모리 초과(OOM)지만, AWQ로 21 tok/s 달성</li>
<li><strong>8GB 메모리 노트북(RTX 4070)</strong>에서도 Llama-2-13B를 <strong>33 tok/s</strong>로 구동 가능</li>
</ol>
<p><strong>시각적 내용 (Figure 9 막대 그래프):</strong></p>
<ul>
<li>파란색(Huggingface FP16): 낮은 막대</li>
<li>회색(TinyChat FP16): 중간 막대</li>
<li>빨간색(TinyChat AWQ): 가장 높은 막대 → 시각적으로도 압도적 우위</li>
</ul>
<hr>
<h2 id="5-결론-및-인사이트-conclusion--insight">5. 결론 및 인사이트 (Conclusion &amp; Insight)</h2>
<h3 id="핵심-기여contribution-3가지">핵심 기여(Contribution) 3가지</h3>
<ol>
<li><p><strong>활성화 인지 양자화 원리 정립</strong><br>가중치 중요도를 활성화 분포로 판단하는 새로운 패러다임 제시. 이는 <strong>GPTQ의 재구성 기반 접근보다 일반화 성능이 뛰어남</strong>을 실험적으로 입증</p>
</li>
<li><p><strong>하드웨어 친화적 설계</strong><br>혼합 정밀도 없이 <strong>단일 비트 양자화 + 채널 스케일링</strong>으로 동등한 효과 달성. 이는 CUDA 커널 구현을 단순화하여 실제 배포 가능성을 높임</p>
</li>
<li><p><strong>범용성 확장</strong>  </p>
<ul>
<li>Instruction-tuned 모델(Vicuna)</li>
<li>멀티모달 모델(OpenFlamingo, VILA, LLaVA)</li>
<li>코딩/수학 특화 모델(CodeLlama, GSM8K)<br>모두에서 우수한 성능 → <strong>첫 범용 저비트 양자화 솔루션</strong></li>
</ul>
</li>
</ol>
<h3 id="한계점-및-향후-과제">한계점 및 향후 과제</h3>
<p><strong>저자가 밝힌 한계:</strong></p>
<ul>
<li>INT2 극저비트에서는 여전히 성능 저하 발생 (Table 9: RTN 완전 실패, AWQ+GPTQ 조합 필요)</li>
<li>보정 데이터 의존도가 낮지만, 완전히 제로는 아님</li>
</ul>
<h2 id="5-참고-문헌-및-링크-references">5. 참고 문헌 및 링크 (References)</h2>
<p><strong>논문 링크:</strong>  </p>
<ul>
<li>arXiv: <a href="https://arxiv.org/abs/2306.00978">https://arxiv.org/abs/2306.00978</a></li>
<li>MLSys 2024 (Best Paper Award)</li>
</ul>
<h2 id="💡-마무리-코멘트">💡 마무리 코멘트</h2>
<p>AWQ는 &quot;LLM 양자화의 JPEG 압축&quot;이라 할 만합니다. JPEG이 이미지에서 인간 눈에 덜 중요한 고주파 성분을 제거하듯, AWQ는 <strong>활성화 분포를 기준으로 덜 중요한 가중치의 정밀도를 낮춥</strong>니다. </p>
<p>특히 인상 깊었던 점은 <strong>이론(수식 유도)과 실무(TinyChat 시스템)를 완벽히 연결</strong>한 연구 설계입니다. 많은 논문이 &quot;이론상 가능&quot;에 그치는 반면, AWQ는 실제 GPU에서 3배 속도 향상을 실측하여 <strong>즉시 도입 가능한 솔루션</strong>임을 증명했습니다.</p>
<p>2024년 기준, 온디바이스 AI가 대세로 떠오르는 시점에서 이 연구는 <strong>모바일 LLM 혁명의 핵심 기술</strong>로 자리매김할 것으로 보입니다. 🚀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[KMMLU: 한국어 대형언어모델의 실전 시험지 – 45개 과목 35,030문항으로 본 한국어 이해력 벤치마크
]]></title>
            <link>https://velog.io/@dev_brojean/KMMLU-%ED%95%9C%EA%B5%AD%EC%96%B4-%EB%8C%80%ED%98%95%EC%96%B8%EC%96%B4%EB%AA%A8%EB%8D%B8%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%8B%9C%ED%97%98%EC%A7%80-45%EA%B0%9C-%EA%B3%BC%EB%AA%A9-35030%EB%AC%B8%ED%95%AD%EC%9C%BC%EB%A1%9C-%EB%B3%B8-%ED%95%9C%EA%B5%AD%EC%96%B4-%EC%9D%B4%ED%95%B4%EB%A0%A5-%EB%B2%A4%EC%B9%98%EB%A7%88%ED%81%AC</link>
            <guid>https://velog.io/@dev_brojean/KMMLU-%ED%95%9C%EA%B5%AD%EC%96%B4-%EB%8C%80%ED%98%95%EC%96%B8%EC%96%B4%EB%AA%A8%EB%8D%B8%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%8B%9C%ED%97%98%EC%A7%80-45%EA%B0%9C-%EA%B3%BC%EB%AA%A9-35030%EB%AC%B8%ED%95%AD%EC%9C%BC%EB%A1%9C-%EB%B3%B8-%ED%95%9C%EA%B5%AD%EC%96%B4-%EC%9D%B4%ED%95%B4%EB%A0%A5-%EB%B2%A4%EC%B9%98%EB%A7%88%ED%81%AC</guid>
            <pubDate>Sun, 16 Nov 2025 06:04:18 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-도입-이-논문을-주목해야-하는-이유">🚀 도입: 이 논문을 주목해야 하는 이유</h3>
<ul>
<li>최근 MMLU(Massive Multitask Language Understanding) 같은 영어 기반 평가표준이 대형언어모델(LLM) 능력을 가늠하는 척도로 널리 쓰이고 있지만, 한국어·한국문화권 환경에서는 번역 기반 데이터에 의존해 왔습니다.</li>
<li>본 논문 KMMLU(Korean Massive Multitask Language Understanding)은 <strong>한국어 시험지 원문 그대로</strong>, 45개 주제, 35,030개의 전문가 수준 객관식 문항을 통해 한국어 모델의 이해력을 측정합니다.</li>
<li>이 논문을 읽고 나면, 한국어 특화 모델이 아직 어디까지 와 있는지, 어떤 영역에서 약한지, 그리고 앞으로 한국어 LLM 연구에 어떤 방향이 필요할지를 알 수 있습니다.</li>
</ul>
<hr>
<h3 id="⏱️-executive-summary">⏱️ Executive Summary</h3>
<p>이 논문은 “한국어 기반 대형언어모델이 얼마나 다양한 주제에서 다중태스크 언어이해를 수행할 수 있는가?”를 묻습니다. 이를 위해 한국어 원문 시험지에서 수집한 35,030문항·45주제의 KMMLU 데이터셋을 제안하고, 27개의 공개 및 상업용 모델을 평가했습니다. 그 결과 최고 성능도 약 60% 수준에 머물러 아직 인간 수준(약 80%)에 크게 못 미치며, 한국어·문화 특화 지식에서 여전히 큰 격차가 존재함을 밝힙니다. </p>
<hr>
<h3 id="🔬-논문-심층-분석-목차별-핵심-요약">🔬 [논문 심층 분석] 목차별 핵심 요약</h3>
<h4 id="1-서론-introduction-무엇이-문제인가"><strong>1. 서론 (Introduction): 무엇이 문제인가?</strong></h4>
<ul>
<li><p><strong>필요성 및 목적</strong></p>
<ul>
<li>한국어 LLM 평가를 위해 기존에 사용된 벤치마크들은 대부분 영어 기반 시험지를 ‘번역’한 형태이므로, 한국어 특유의 문법·사회문화적 배경이 반영되지 않고 있다는 문제를 제시합니다.</li>
<li>따라서 한국어·한국문화권 사용자에게 적합한 평가 데이터가 필요하며, 본 연구는 그 해결책으로 KMMLU를 제안합니다.</li>
</ul>
</li>
<li><p><strong>연구 갭(Research Gap)</strong></p>
<ul>
<li>단순 번역된 데이터는 자연스러움이나 문맥 적합성에서 한계를 지니고 있으며, 영어권 중심 지식(예: 미국 법률, 영어 속어 등)에 편향되어 있다는 지적이 있습니다.</li>
<li>한국어 모델이 현재 얼마나 한국어·한국문화 맥락에서 이해력을 보여주는지 제대로 평가된 바 없다는 점이 지적됩니다.</li>
</ul>
</li>
</ul>
<h4 id="2-이론적-배경--선행-연구-literature-review"><strong>2. 이론적 배경 / 선행 연구 (Literature Review):</strong></h4>
<ul>
<li>핵심 개념은 ‘다중태스크 언어이해’(multitask language understanding)와 ‘언어·문화 특화된 평가’입니다. 벤치마크라는 도구가 LLM 성능을 추적하고 비교하는 데 필수적이라는 인식이 있습니다.</li>
<li>기존 한국어 평가자료로는 KLUE 등이 존재하지만, 내용이 번역에 의존하거나 평가 영역이 제한적이었음을 논문에서 언급합니다.</li>
<li>본 연구의 차별점은 “한국어 시험 원문 기반”, “한국문화 맥락 반영”, “45개 주제·35k 문항 규모”라는 점입니다.</li>
</ul>
<h4 id="3-연구-방법론-methodology-어떻게-증명했는가"><strong>3. 연구 방법론 (Methodology): 어떻게 증명했는가?</strong></h4>
<ul>
<li><p><strong>연구 질문</strong></p>
<ul>
<li>한국어 LLM이 다양한 주제(인문·사회과학부터 STEM까지)에서 얼마나 잘 수행하는가?</li>
<li>한국어·한국문화 특화 지식이 필요한 문항에서 기존 모델들은 어느 정도까지 대응 가능한가?</li>
</ul>
</li>
<li><p><strong>데이터 구축</strong></p>
<ul>
<li>한국어 원본 시험지(국가시험, 자격시험 등)에서 문항 371,002개 수집 → 필터링·정제 → 최종 35,030문항 (테스트 세트) 마련. </li>
<li>각 문항이 한국어 자연어 표현과 한국 문화·제도 맥락을 갖추도록 설계됨. 예컨대 “한국사”, “세무”, “형법” 등 한국 고유 지식이 필요한 영역 포함.</li>
</ul>
</li>
<li><p><strong>평가 실험</strong></p>
<ul>
<li>27개의 공개 및 상업용 모델을 45개 주제에 걸쳐 평가. 대표적으로 GPT‑4, HyperCLOVA X, Polyglot‑Ko 등이 포함됨. </li>
<li>평가 방식은 다지선다형(MCQA, Multiple Choice Question Answering)으로, Direct 방식(답변 직접 생성)과 CoT 방식(Chain-of-Thought, 추론 과정 포함) 등이 사용됩니다.</li>
</ul>
</li>
</ul>
<h4 id="4-연구-결과-results-무엇을-발견했는가"><strong>4. 연구 결과 (Results): 무엇을 발견했는가?</strong></h4>
<ul>
<li><p><strong>핵심 결과</strong></p>
<ul>
<li>가장 우수한 모델도 약 <strong>59.95%</strong> 수준의 정확도를 기록했고, 일반 공개 모델은 약 <strong>50.5%</strong> 수준이었으며, 인간 기준 합격선(출제 시험 수준)인 약 80%에는 크게 미치지 못했습니다.</li>
<li>한국어 특화 모델이 반드시 다국어 대형 모델보다 우수하지 않다는 점이 관찰되었습니다. 예컨대 ‘한국사’ 등 문화·제도 지식이 필요한 영역에서 성능이 매우 낮았습니다.</li>
<li>“다국어 모델 확대 = 모든 언어에서 잘한다”는 단순 기대가 항상 맞지 않음을 보여줍니다. 연구팀은 다국어 확장이 오히려 특정 언어의 문화·지식 이해에는 제약이 될 수 있음을 논의합니다. </li>
</ul>
</li>
<li><p><strong>데이터/분류별 분석</strong></p>
<ul>
<li>STEM 분야보다는 한국사·법률·세무 등 문화·제도 지식 요구 영역에서 모델 성능이 상대적으로 낮게 나타났습니다.</li>
<li>Chain-of-Thought(추론 과정 포함) 프롬프트가 일부 모델에서 성능을 개선했지만, 모든 분야에서 강력한 대안은 아니었습니다.</li>
</ul>
</li>
</ul>
<h4 id="5-결론-및-제언-conclusion--discussion-이-연구가-왜-중요한가"><strong>5. 결론 및 제언 (Conclusion &amp; Discussion): 이 연구가 왜 중요한가?</strong></h4>
<ul>
<li><p><strong>의미(Implication)</strong></p>
<ul>
<li>한국어 LLM 평가에 있어 번역된 영어시험지 기반 접근이 가진 한계를 명확히 드러냈고, 한국어·문화 기반의 평가 데이터의 중요성을 강조합니다.</li>
<li>향후 한국어 모델 개발·평가의 기준점이 될 수 있는 ‘실전형’ 벤치마크를 제시했다는 점에서 학술적·실무적으로 의미가 큽니다.</li>
</ul>
</li>
<li><p><strong>저자가 밝힌 한계 및 향후 연구 제언</strong></p>
<ul>
<li>저작권 문제로 인해 <strong>한국어·의료·금융 분야</strong>에서 일부 문항이 제외되어 있어 커버리지에 제한이 있음을 언급합니다.</li>
<li>다지선다형 문제에 집중했다는 점에서 <strong>생성형 응답, 대화형 태스크, 장문 추론 등</strong> 다른 유형의 평가가 필요하다는 제언이 있습니다.</li>
<li>또한 앞으로 모델이 한국어·한국문화 특화 데이터를 얼마나 포함해야 하는가, 평가 방식이나 프롬프트 설계 개선 등의 과제가 남아 있다고 제안하고 있습니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="🧐-핵심-인사이트-및-시사점">🧐 핵심 인사이트 및 시사점</h3>
<ul>
<li><p><strong>가장 중요한 인사이트</strong>는 “언어모델이 단순히 언어를 처리하는 것만이 아니라 <strong>문화·제도·맥락</strong>을 얼마나 이해하느냐가 성능 격차를 만든다”는 점입니다. 한국어처럼 문화적·제도적 배경이 중요한 언어에서는 이 부분이 핵심입니다.</p>
</li>
<li><p><strong>현업 적용 관점에서의 시사점</strong></p>
<ul>
<li>한국어 서비스를 위한 챗봇, AI 어시스턴트, 교육 플랫폼 등에서 “한국어·한국 문화 이해” 수준을 평가하는 내부 벤치마크로 KMMLU와 같은 데이터를 고려할 수 있습니다.</li>
<li>모델 선택 시 단순히 파라미터 크기나 영어 성능만 본다면 한국어·한국문화 맥락에서의 성능 저하 문제를 미리 고려해야 합니다.</li>
<li>한국어 모델을 개발할 때, 학습 데이터 확보, 한국 제도·문화지식 반영, 평가 지표 설계 등을 KMMLU가 제시한 방향을 참고할 수 있습니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="⚠️-비판적-검토-논문의-한계와-생각해-볼-점">⚠️ [비판적 검토] 논문의 한계와 생각해 볼 점</h3>
<ul>
<li><p><strong>추가 아쉬운 점 및 맹점</strong></p>
<ul>
<li>다지선다형 객관식만으로 평가한다는 점에서, 실제 언어모델 응용 환경(예: 생성, 대화, 자유 형식 답변)과의 연결성이 제한적일 수 있습니다.</li>
<li>시험지 기반 문항이라는 특성상 “한국어 시험문항 특화” 경향이 있어, 일반 언어이해·일상대화·창의적 사고 등으로 바로 일반화하기엔 제약이 있습니다.</li>
<li>평가된 모델들의 학습 데이터·파라미터·훈련 방식이 다양하므로, 성능 격차의 원인이 “한국어 데이터 부족”인지 “구조적 한계”인지 분리하기 어렵다는 점이 있습니다.</li>
</ul>
</li>
<li><p><strong>독자들이 주의해야 할 점 및 추가 질문</strong></p>
<ul>
<li>KMMLU에서 낮은 점수를 기록했다고 해서 해당 모델이 “모든 한국어 작업에 실패한다”고 단정하긴 어렵습니다. 특정 형태의 문항(시험형 객관식)에 특화되어 있다는 점을 기억해야 합니다.</li>
<li>향후 생성형 태스크 혹은 한국어 대화·리서치형 응용에서 동일한 격차가 존재하는지 여부는 아직 열려있는 질문입니다.</li>
<li>또한 한국어 모델 개발 시 “문화·제도 지식 포함”이라는 요소가 얼마나 비용 대비 효과적인가, 데이터 확보·정제 비용 등을 고려할 필요가 있습니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="📌-마무리하며">📌 마무리하며</h3>
<p>오늘 리뷰한 논문을 한 문장으로 정리하자면:</p>
<blockquote>
<p><strong>“한국어와 한국문화 맥락을 반영한 대형언어모델 평가를 위해, KMMLU라는 대규모·다주제 벤치마크가 필요한 기준점을 제공했다.”</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[MobileLLM: Optimizing Sub‑billion Parameter Language Models for On‑Device Use Cases]]></title>
            <link>https://velog.io/@dev_brojean/MobileLLM-Optimizing-Subbillion-Parameter-Language-Models-for-OnDevice-Use-Cases</link>
            <guid>https://velog.io/@dev_brojean/MobileLLM-Optimizing-Subbillion-Parameter-Language-Models-for-OnDevice-Use-Cases</guid>
            <pubDate>Sun, 16 Nov 2025 05:35:45 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-도입-이-논문을-주목해야-하는-이유">🚀 도입: 이 논문을 주목해야 하는 이유</h3>
<p>오늘날 대형 언어모델(LLM: Large Language Model)은 놀라운 성능을 보여주지만, 대부분이 <strong>클라우드 연산에 의존</strong>하고 있습니다. 그로 인해 <strong>지연(latency), 비용, 에너지 소비, 모바일·엣지 단말에서의 메모리 제약</strong> 등이 현실적 문제로 떠오르고 있죠. 이 논문은 바로 이러한 문제 맥락에서, <strong>모바일이나 에지 환경에서도 실용적으로 사용할 수 있는 ‘10억 파라미터 미만(Sub-billion parameter)’ 언어모델의 설계와 최적화</strong>를 다룹니다.
읽고 나면 독자들은 다음을 얻게 됩니다:</p>
<ul>
<li>왜 단순히 파라미터 수나 데이터량만 늘리는 방식이 항상 정답이 아닌지</li>
<li>모바일/엣지 환경에 적합한 모델 설계 관점에서 중요한 아키텍처 요소들이 무엇인지</li>
<li>실제 성능 향상 및 온디바이스 적용 가능성이 어떤 수준인지</li>
</ul>
<hr>
<h3 id="⏱️-executive-summary">⏱️ Executive Summary</h3>
<p>이 논문은 “모바일·엣지 환경에 적합하게 10억 미만 파라미터의 언어모델을 설계할 수 있을까?”라는 질문을 던집니다. 해법으로 <strong>깊고 얇은(deep &amp; thin) 아키텍처</strong>, <strong>입·출력 임베딩 공유(embedding sharing)</strong>, <strong>그룹 쿼리 어텐션(grouped-query attention)</strong> 등을 도입하여, 기존 125 M/350 M급 모델 대비 각각 약 2.7%/4.3% 정확도 향상을 달성했습니다. 더 나아가 <strong>블록 단위 가중치 공유(immediate block-wise weight sharing)</strong>를 추가한 버전(MobileLLM-LS)은 동일 크기에서 추가 0.7%/0.8% 향상을 보였습니다. 이는 “작은 모델도 제대로 설계하면 꽤 강하다”는 중요한 메시지를 던져줍니다. </p>
<hr>
<h3 id="🔬-논문-심층-분석-목차별-핵심-요약">🔬 [논문 심층 분석] 목차별 핵심 요약</h3>
<h4 id="1-서론-introduction-무엇이-문제인가"><strong>1. 서론 (Introduction): 무엇이 문제인가?</strong></h4>
<ul>
<li>저자들은 모바일·엣지 기기에서의 LLM 적용이 <strong>메모리 제약</strong>(예: DRAM 용량), <strong>지연/응답 속도</strong>, <strong>클라우드 의존에 따른 비용 및 에너지 소비 증가</strong> 등의 현실적 제약에 직면해 있다고 지적합니다. </li>
<li>특히, 대형 모델들을 그대로 모바일에 올리는 것은 현실적이지 않으며, 따라서 <strong>10억 미만 파라미터(즉 sub-billion scale)</strong> 모델이 현실적 대안이 될 수 있다는 인식을 제시합니다.</li>
<li>기존 연구에서는 주로 ‘더 많은 파라미터 + 더 많은 데이터’가 성능을 결정짓는 핵심이라고 여겨졌지만, 본 논문은 “이 규모 이하에서는 모델 아키텍처가 훨씬 더 중요하다”는 연구 갭(Research Gap)을 제시합니다.</li>
<li>따라서 본 연구의 목적은 다음과 같습니다: <strong>모바일 사용 환경에 적합하게 작고 효율적인 언어모델을 설계하고</strong>, 이를 통해 기존 동일 규모 모델 대비 성능을 향상시킨다는 것.</li>
</ul>
<h4 id="2-이론적-배경--선행-연구-literature-review"><strong>2. 이론적 배경 / 선행 연구 (Literature Review):</strong></h4>
<ul>
<li><p>논문은 먼저 기존 대형언어모델의 스케일링 법칙(scaling laws) — 파라미터 수, 학습 데이터 양, 연산량 등이 모델 성능을 결정한다는 — 을 요약합니다.</p>
</li>
<li><p>하지만 소형모델(sub-billion scale)에서는 이러한 법칙이 그대로 적용되지 않을 수 있으며, 실제로 <strong>아키텍처 설계 변화가 성능에 유의미한 영향을 미칠 수 있다</strong>는 선행 연구들을 언급합니다.</p>
</li>
<li><p>또한, 임베딩 공유(embedding sharing), 레이어 공유(layer sharing), 어텐션 구조 최적화(attention mechanism) 등의 경량화 및 효율화 기법들이 그간 제안되어 왔습니다.</p>
</li>
<li><p>본 논문이 가진 <strong>차별점</strong>은:</p>
<ul>
<li>단순히 프루닝(pruning), 양자화(quantization) 또는 지식증류(distillation)를 넘어 <strong>아키텍처 설계</strong>(깊고 얇은 구조, grouped-query attention 등) 자체를 중심에 두었다는 점</li>
<li>모바일/엣지 환경에서의 실제 사용 가능성까지 고려했다는 점</li>
<li>동일한 파라미터 범위 내에서 기존 대비 성능 향상을 명시적으로 보여주었다는 점</li>
</ul>
</li>
</ul>
<h4 id="3-연구-방법론-methodology-어떻게-증명했는가"><strong>3. 연구 방법론 (Methodology): 어떻게 증명했는가?</strong></h4>
<ul>
<li><p>연구 질문(Research Question)은 크게 “작은 규모 언어모델에서도 아키텍처 개선으로 성능을 의미있게 향상시킬 수 있는가?” 그리고 “그 향상된 모델이 모바일·엣지 환경에 실제로 배포 가능한 수준인가?” 등으로 요약됩니다.</p>
</li>
<li><p>데이터 및 실험 설정: 논문에서는 다양한 규모 (예: 125M, 350M 등)의 모델을 대상으로 제안된 설계 요소들의 효과를 <strong>제로샷(zero-shot) 상식추론</strong>, 질문응답(task) 등 여러 벤치마크에서 평가했습니다.</p>
</li>
<li><p>핵심 설계요소:</p>
<ol>
<li><strong>SwiGLU 활성화 함수</strong>: 기존 ReLU 기반 FFN(feed-forward network) 대신 SwiGLU를 채택하여 비선형성을 강화했습니다.</li>
<li><strong>깊고 얇은(Deep &amp; Thin) 아키텍처</strong>: 동일한 파라미터 수라면 레이어 수(Layers)를 늘이고 각 레이어 폭(width)을 줄이는 구조가 성능에 유리하다는 실험적 증거를 제시했습니다.</li>
<li><strong>임베딩 공유(Embedding Sharing)</strong>: 소형 모델에서는 임베딩 층이 전체 파라미터에서 차지하는 비중이 커지므로, 입력(Input) 및 출력(Output) 임베딩을 공유함으로써 파라미터 절감과 효율화를 이루었습니다. </li>
<li><strong>그룹 쿼리 어텐션(Grouped-Query Attention, GQA)</strong>: 쿼리 헤드(Query head)를 그룹화하고 키/값 헤드(Key/Value) 수를 줄여 어텐션 연산을 효율화하면서도 성능을 유지하는 구조를 도입했습니다.</li>
<li><strong>블록 단위 가중치 공유(Block-wise Weight Sharing)</strong>: 모델의 크기를 늘리지 않으면서도 레이어 간 가중치를 공유해 추가 성능 향상을 꾀한 방식입니다. </li>
</ol>
</li>
<li><p>실험 설계에서는 위 요소들을 조합한 모델군(예: MobileLLM-125M, MobileLLM-350M, 그리고 레이어 공유 버전인 MobileLLM-LS)과 기존 동종 규모 모델을 비교하였습니다.</p>
</li>
</ul>
<h4 id="4-연구-결과-results-무엇을-발견했는가"><strong>4. 연구 결과 (Results): 무엇을 발견했는가?</strong></h4>
<ul>
<li><p>핵심 실험 결과는 다음과 같습니다:</p>
<ul>
<li>MobileLLM-125M/350M 모델이 기존 동종 규모 모델 대비 각각 약 <strong>2.7% / 4.3%</strong> 정확도 향상을 보였습니다.</li>
<li>블록 단위 가중치 공유를 적용한 MobileLLM-LS 버전은 동일 크기에서 추가로 약 <strong>0.7% / 0.8%</strong> 향상된 성능을 보여주었습니다. </li>
<li>채팅(chat) 벤치마크에서도 소형 모델임에도 우수한 성능을 보였으며, 어떤 API 호출(tasks)에서는 LLaMA‑v2-7B급 모델과 <strong>근접한 정밀도</strong>를 기록했다는 보고가 있습니다.</li>
</ul>
</li>
<li><p>또한 배포 관점에서 실제 모바일 환경 적용 가능성을 고려한 결과도 제시되어 있습니다. 예컨대, 메모리·지연·에너지 측면에서 소형 모델이 유리하다는 언급이 있습니다. </p>
</li>
<li><p>종합하면, 이 논문은 “같은 파라미터 예산이라면 아키텍처 설계가 성능을 결정짓는 중요한 축이 될 수 있다”는 실증적 근거를 제공합니다.</p>
</li>
</ul>
<h4 id="5-결론-및-제언-conclusion--discussion-이-연구가-왜-중요한가"><strong>5. 결론 및 제언 (Conclusion &amp; Discussion): 이 연구가 왜 중요한가?</strong></h4>
<ul>
<li><p>이 연구는 <strong>학술적 의의</strong>로 보면, 소형 언어모델 설계에 있어 파라미터 수·데이터량 중심의 관점에서 벗어나 <strong>아키텍처 중심의 설계 전략</strong>을 제안했다는 점이 중요합니다.</p>
</li>
<li><p><strong>실무적 의미</strong>로 보면, 모바일·엣지 기기에서 직접 언어모델을 구동하려는 개발자나 제품 관점에서 매우 유의미한 설계 가이드를 제공한다는 점입니다. 즉, “무조건 크고 비싼 모델을 쓰자”는 접근이 아니라 “환경 제약을 고려한 설계”의 가능성을 열어주었다고 볼 수 있습니다.</p>
</li>
<li><p>논문에서 저자들이 밝힌 <strong>한계점 및 향후 연구 제언</strong>은 다음과 같습니다:</p>
<ul>
<li>본 연구는 주로 제로샷 상식추론 및 채팅 벤치마크에 집중되어 있으며, <strong>더 복잡하거나 도메인 특화된 작업</strong>에 대한 검증은 제한적입니다.</li>
<li>또한, 온디바이스 실제 제품화 과정에서의 배포·최적화·전력소모·실시간 응답성 등 <strong>엔드투엔드(end-to-end) 구현 과제</strong>는 아직 남아 있다고 합니다.</li>
<li>향후 연구로는 <strong>더 낮은 비트 양자화(low-bit quantization), 긴 컨텍스트(long-context) 지원, 다양한 기기 환경에서의 실험</strong>, 그리고 <strong>더 작은 모델의 추가적 경량화</strong> 등이 제안되어 있습니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="🧐-핵심-인사이트-및-시사점">🧐 핵심 인사이트 및 시사점</h3>
<ul>
<li><p><strong>인사이트:</strong> 이 논문에서 가장 주목할 만한 관점은 “작은 모델에서도 아키텍처의 설계가 매우 중요하다”는 점입니다. 특히 모바일·엣지 환경처럼 자원이 제한된 상황에서는 파라미터 수를 무작정 늘리는 것보다 <strong>모델의 깊이/폭 조정, 임베딩 공유, 어텐션 구조 최적화</strong> 등이 더 큰 효과를 낼 수 있다는 사실이 설계자들에게 중요한 시사점을 줍니다.</p>
</li>
<li><p><strong>실무 적용:</strong> 제품화 관점에서 이 논문의 방법론을 적용해 보면 아래와 같은 방식이 가능합니다:</p>
<ul>
<li>모바일 앱 내 언어모델 탑재 시, 1 억~3 억 파라미터 수준에서 <strong>깊고 얇은 레이어 구조</strong>를 설계해 보세요.</li>
<li>임베딩 계층이 차지하는 메모리 비중이 큰 경우, <strong>입출력 임베딩 공유</strong>를 통해 파라미터 절감과 메모리 효율을 함께 도모할 수 있습니다.</li>
<li>어텐션 구조에서 키/값 헤드 수를 줄이고 쿼리 헤드를 그룹화하는 방식(GQA)을 통해 저지연·저자원 환경에서의 효율을 개선할 수 있습니다.</li>
<li>가중치 공유 기법을 도입하면 모델 크기를 크게 키우지 않고도 성능 향상을 꾀할 수 있으므로, 실제 배포 전 실험 단계에서 고려할 만합니다.</li>
<li>이러한 설계 전략은 특히 <strong>인터넷 연결이 불안정하거나 지연이 중요한 모바일/엣지 애플리케이션</strong> (예: 오프라인 챗봇, 실시간 음성/텍스트 인터페이스 등)에서 경쟁력을 가질 수 있습니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="⚠️-비판적-검토-논문의-한계와-생각해-볼-점">⚠️ [비판적 검토] 논문의 한계와 생각해 볼 점</h3>
<ul>
<li><p>저자가 제시한 한계 외에, 제가 보기에 다음과 같은 추가적인 아쉬움이나 맹점이 존재합니다:</p>
<ul>
<li><strong>데이터·도메인 다양성:</strong> 논문이 주로 상식추론, 채팅 등 범용 태스크에 집중되어 있고, 의료·법률·특수언어 등 <strong>도메인 특화 작업</strong>에서 이 설계가 동일한 수준으로 작동할지는 아직 검증이 부족합니다.</li>
<li><strong>배포·실시간 환경의 복잡성:</strong> 논문에서 모델 아키텍처 수준의 효율을 제시했지만, 실제 모바일 앱/엣지 기기에서의 메모리 파편화, 배터리 소비, OS 간섭, 사용자 인터페이스 등의 요소까지 포함하면 현실적인 배포 과정에서 추가 과제들이 있을 수 있습니다.</li>
<li><strong>스케일링의 한계:</strong> “작은 모델에서도 효과적이다”는 결론이 나오긴 했지만, 어디까지 이 전략이 <strong>더 작은 규모나 더 복잡한 작업</strong>에 적용 가능한가 하는 경계가 명확치 않습니다. 예컨대 수백만 파라미터 이하, 또는 수십억 컨텍스트 길이를 요구하는 작업에서는 여전히 큰 모델이 유리할 수 있습니다.</li>
<li>이 논문의 결과를 받아들일 때 다음 점을 유의해야 합니다: 제시된 성능 향상 수치는 특정 벤치마크·조건 하에서 산출된 것이며, <strong>모든 환경에서 동일한 향상을 보장하지 않습니다</strong>. 따라서 자신의 제품 환경과 태스크 환경에 맞추어 실험을 하는 것이 중요합니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="📌-마무리하며">📌 마무리하며</h3>
<p>한 문장으로 정리하자면:</p>
<blockquote>
<p><strong>“모바일·엣지 환경에서도 설계만 잘하면 ‘10억 미만’ 언어모델로 꽤 강력한 성능을 낼 수 있다.”</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[개발공부] 싱글톤(Singleton) 과 추상 메서드(Abstract Method)]]></title>
            <link>https://velog.io/@dev_brojean/%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80-%EC%8B%B1%EA%B8%80%ED%86%A4Singleton-%EA%B3%BC-%EC%B6%94%EC%83%81-%EB%A9%94%EC%84%9C%EB%93%9CAbstract-Method</link>
            <guid>https://velog.io/@dev_brojean/%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80-%EC%8B%B1%EA%B8%80%ED%86%A4Singleton-%EA%B3%BC-%EC%B6%94%EC%83%81-%EB%A9%94%EC%84%9C%EB%93%9CAbstract-Method</guid>
            <pubDate>Thu, 28 Aug 2025 12:28:12 GMT</pubDate>
            <description><![CDATA[<ul>
<li><strong>싱글톤</strong>: “프로그램에서 딱 1개만 있어야 하는 객체” 만들기. (설정/로거/커넥션 등)</li>
<li><strong>추상 메서드</strong>: “자식이 반드시 구현해야 할 메서드” 강제(팀 규약 만들기).</li>
<li>파이썬은 <strong>모듈 전역 객체</strong>가 사실상 싱글톤처럼 동작. 필요하면 <code>__new__</code>+Lock, 또는 메타클래스로 확장.</li>
</ul>
<hr>
<h2 id="1-싱글톤-진짜로-한-개만-만들기">1) 싱글톤: 진짜로 한 개만 만들기</h2>
<h3 id="1-1-제일-쉬운-방법-모듈-전역-객체">1-1. 제일 쉬운 방법: <strong>모듈 전역 객체</strong></h3>
<p>파이썬은 모듈을 한 번만 로드해요. 그래서 모듈 전역에 올려두면 사실상 싱글톤처럼 굴어요.
저는 설정 관리에 이렇게 씁니다.</p>
<p><strong>settings.py</strong></p>
<pre><code class="language-python"># settings.py
class Settings:
    def __init__(self):
        self.debug = False
        self.theme = &quot;light&quot;

settings = Settings()  # ← 모듈 전역: 사실상 싱글톤</code></pre>
<p><strong>app.py</strong></p>
<pre><code class="language-python"># app.py
from settings import settings

def main():
    print(&quot;초기:&quot;, settings.debug, settings.theme)  # False light
    settings.debug = True
    settings.theme = &quot;dark&quot;
    other()  # 다른 함수(다른 파일이어도 OK)
    print(&quot;마무리:&quot;, settings.debug, settings.theme)

def other():
    from settings import settings
    print(&quot;other에서 보는 값:&quot;, settings.debug, settings.theme)  # True dark (동일 인스턴스)

if __name__ == &quot;__main__&quot;:
    main()</code></pre>
<p><strong>실행하면 대충 이런 로그가 떠요</strong></p>
<pre><code>초기: False light
other에서 보는 값: True dark
마무리: True dark</code></pre><blockquote>
<p>✔️ 간단하고 실전에서 제일 많이 씀. “진짜 클래스로 싱글톤 만들어야 하나?” 싶으면 <strong>이걸 먼저 고려</strong>하세요.</p>
</blockquote>
<hr>
<h3 id="1-2-클래스로-구현-__new__--lock-스레드-안전-버전">1-2. 클래스로 구현: <code>__new__</code> + <strong>Lock</strong> (스레드 안전 버전)</h3>
<p>여러 스레드가 동시에 만들어도 <strong>딱 한 개</strong>만 생기게 하고 싶을 때 썼습니다.</p>
<pre><code class="language-python"># singleton_config.py
import threading
import concurrent.futures

class Config:
    _instance = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        # double-checked locking
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        # __init__는 여러 번 불릴 수 있어서 가드 필요
        if getattr(self, &quot;_initialized&quot;, False):
            return
        self._initialized = True
        self._data = {}

    def set(self, k, v): self._data[k] = v
    def get(self, k, d=None): return self._data.get(k, d)

if __name__ == &quot;__main__&quot;:
    def worker(i):
        c = Config()
        c.set(&quot;last_writer&quot;, i)
        return id(c)

    with concurrent.futures.ThreadPoolExecutor(max_workers=8) as ex:
        ids = list(ex.map(worker, range(50)))

    print(&quot;인스턴스 id 개수:&quot;, len(set(ids)))   # 1이면 성공
    print(&quot;마지막 작성자:&quot;, Config().get(&quot;last_writer&quot;))</code></pre>
<p><strong>제 실행 결과(예)</strong></p>
<pre><code>인스턴스 id 개수: 1
마지막 작성자: 49</code></pre><blockquote>
<p>✔️ TIL: <code>__init__</code>는 여러 번 불릴 수 있으니 <code>_initialized</code> 가드 없으면 초기화가 <strong>중복</strong>됩니다.</p>
</blockquote>
<hr>
<h3 id="1-3-여러-클래스를-싱글톤으로-→-메타클래스-한-방">1-3. 여러 클래스를 싱글톤으로? → <strong>메타클래스</strong> 한 방</h3>
<p>로거/메트릭 등 여러 타입을 각각 싱글톤으로 만들고 싶을 때 편했어요.</p>
<pre><code class="language-python"># singleton_meta.py
import threading

class SingletonMeta(type):
    _instances = {}
    _lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls not in cls._instances:
                cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class Logger(metaclass=SingletonMeta):
    def __init__(self): self.history = []
    def log(self, msg):
        self.history.append(msg)
        print(f&quot;[LOG] {msg}&quot;)

class Metrics(metaclass=SingletonMeta):
    def __init__(self): self.counters = {}
    def incr(self, key, n=1): self.counters[key] = self.counters.get(key, 0) + n

if __name__ == &quot;__main__&quot;:
    a, b = Logger(), Logger()
    print(&quot;로거 동일?&quot;, id(a) == id(b))  # True
    a.log(&quot;hello&quot;); b.log(&quot;world&quot;)
    print(&quot;히스토리:&quot;, a.history)       # [&#39;hello&#39;, &#39;world&#39;]</code></pre>
<p><strong>짧은 메모</strong></p>
<ul>
<li>공용 Lock으로 간단히 스레드 안전 확보.</li>
<li>“클래스별로 한 개씩”이 필요할 때 깔끔.</li>
</ul>
<hr>
<h3 id="1-4-제가-당한-실수-모음">1-4. 제가 당한(…) 실수 모음</h3>
<ul>
<li><strong>전역 상태 남발</strong>: 테스트 지옥. 가능하면 의존성 주입(함수/생성자 인자) 섞어 쓰기.</li>
<li><strong>초기화 중복</strong>: <code>__init__</code> 가드 빼먹으면 값이 자꾸 리셋됨.</li>
<li><strong>멀티스레딩</strong>: Lock 없이 싱글톤 만들었다가 2개 생긴 적 있음…(테스트에서만 뜨는 유령 버그 느낌)</li>
</ul>
<hr>
<h2 id="2-추상-메서드-팀-규약계약-강제하기">2) 추상 메서드: 팀 규약(계약) 강제하기</h2>
<h3 id="2-1-핵심-개념-한-줄">2-1. 핵심 개념 한 줄</h3>
<p>**“자식 클래스가 반드시 구현해야 하는 메서드”**를 선언해두는 것.
파이썬에선 <code>abc</code> 모듈의 <code>ABC</code>, <code>@abstractmethod</code> 사용.</p>
<h3 id="2-2-제일-작은-예제-동물-울음">2-2. 제일 작은 예제: 동물 울음</h3>
<pre><code class="language-python"># abstract_animal.py
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def speak(self) -&gt; str: ...

class Dog(Animal):
    def speak(self) -&gt; str: return &quot;멍멍&quot;

class Cat(Animal):
    def speak(self) -&gt; str: return &quot;야옹&quot;

if __name__ == &quot;__main__&quot;:
    pets = [Dog(), Cat()]
    for p in pets: print(p.speak())
    # Animal()  # ← TypeError: 추상 메서드 남아있어서 인스턴스화 불가</code></pre>
<p><strong>실행 느낌</strong></p>
<pre><code>멍멍
야옹</code></pre><blockquote>
<p>✔️ <code>Animal()</code>은 직접 못 만듭니다. 자식이 <code>speak</code>를 <strong>반드시</strong> 구현해야 해요.</p>
</blockquote>
<hr>
<h3 id="2-3-실전-예제-결제-인터페이스-통일">2-3. 실전 예제: 결제 인터페이스 통일</h3>
<p>개발하면서 <strong>결제수단을 늘려도 호출부 코드를 안 고치고</strong> 싶어서 이렇게 잡았습니다.</p>
<pre><code class="language-python"># payment.py
from abc import ABC, abstractmethod

class PaymentProcessor(ABC):
    @property
    @abstractmethod
    def name(self) -&gt; str: ...

    @abstractmethod
    def pay(self, amount: int) -&gt; None: ...

class CardProcessor(PaymentProcessor):
    def __init__(self, merchant_id: str):
        self._merchant_id = merchant_id

    @property
    def name(self) -&gt; str: return &quot;CARD&quot;

    def pay(self, amount: int) -&gt; None:
        print(f&quot;[{self.name}] 승인 {amount}원 (MID={self._merchant_id})&quot;)

class BankTransferProcessor(PaymentProcessor):
    @property
    def name(self) -&gt; str: return &quot;BANK_TRANSFER&quot;

    def pay(self, amount: int) -&gt; None:
        print(f&quot;[{self.name}] 계좌이체 {amount}원 처리&quot;)

def checkout(processor: PaymentProcessor, amount: int):
    print(f&quot;결제 시작: {processor.name} / {amount}원&quot;)
    processor.pay(amount)
    print(&quot;결제 완료\n&quot;)

if __name__ == &quot;__main__&quot;:
    checkout(CardProcessor(&quot;M1234&quot;), 15000)
    checkout(BankTransferProcessor(), 39000)</code></pre>
<p><strong>실행하면</strong></p>
<pre><code>결제 시작: CARD / 15000원
[CARD] 승인 15000원 (MID=M1234)
결제 완료

결제 시작: BANK_TRANSFER / 39000원
[BANK_TRANSFER] 계좌이체 39000원 처리
결제 완료</code></pre><p><strong>제가 좋았던 점</strong></p>
<ul>
<li>호출부(<code>checkout</code>)는 <strong>인터페이스만 믿고 호출</strong>. 새 결제수단 추가해도 수정 없음.</li>
<li>팀에 “필수 메서드/프로퍼티”를 <strong>강제</strong>할 수 있어 코드가 일정해짐.</li>
</ul>
<hr>
<h3 id="2-4-추상-메서드-관련-til">2-4. 추상 메서드 관련 TIL</h3>
<ul>
<li><code>@property</code>에도 <code>@abstractmethod</code>를 같이 써서 <strong>추상 프로퍼티</strong> 만들 수 있음.</li>
<li>클래스/정적 메서드도 추상화 가능 (<code>@classmethod</code>/<code>@staticmethod</code>와 함께).</li>
<li>구현 하나라도 빼먹으면 <strong>인스턴스화 시점에</strong> 바로 에러를 줘서 초반에 잡음.</li>
</ul>
<hr>
<h2 id="3-콤보-싱글톤-설정--추상-메서드-결제">3) 콤보: <strong>싱글톤 설정</strong> + <strong>추상 메서드 결제</strong></h2>
<p>“설정은 한 개”, “결제는 여러 구현”을 동시에 쓰면 아래처럼 됩니다.</p>
<pre><code class="language-python"># combo_example.py
from abc import ABC, abstractmethod
import threading

# --- Singleton Settings ---
class Settings:
    _instance = None
    _lock = threading.Lock()
    def __new__(cls):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance
    def __init__(self):
        if getattr(self, &quot;_initialized&quot;, False): return
        self._initialized = True
        self.api_key = &quot;DUMMY_API_KEY&quot;
        self.currency = &quot;KRW&quot;

# --- Abstract Payment Interface ---
class Payment(ABC):
    @abstractmethod
    def pay(self, amount: int) -&gt; None: ...

class CardPayment(Payment):
    def __init__(self):
        self.settings = Settings()  # 싱글톤 주입
    def pay(self, amount: int) -&gt; None:
        print(f&quot;[CARD] {amount}{self.settings.currency} 결제 (API={self.settings.api_key})&quot;)

class TransferPayment(Payment):
    def __init__(self):
        self.settings = Settings()  # 싱글톤 주입
    def pay(self, amount: int) -&gt; None:
        print(f&quot;[BANK] {amount}{self.settings.currency} 이체 (API={self.settings.api_key})&quot;)

def order(processor: Payment, amount: int):
    processor.pay(amount)

if __name__ == &quot;__main__&quot;:
    s = Settings()
    s.currency = &quot;KRW&quot;  # 한 번 바꾸면 모든 결제에서 같은 설정 사용
    order(CardPayment(), 12000)
    order(TransferPayment(), 45000)</code></pre>
<p><strong>제 실행 결과</strong></p>
<pre><code>[CARD] 12000KRW 결제 (API=DUMMY_API_KEY)
[BANK] 45000KRW 이체 (API=DUMMY_API_KEY)</code></pre><hr>
<h2 id="4-유지보수-팁-실무-감각">4) 유지보수 팁 (실무 감각)</h2>
<ul>
<li><strong>전역 싱글톤 최소화</strong>: 정말 공용이어야 하는 것만(설정/로거). 도메인 로직은 가급적 <strong>의존성 주입</strong>으로.</li>
<li><strong>인터페이스 먼저 잡기</strong>: 추상 메서드로 규약부터 잡으면, 팀원이 병렬로 구현하기 쉬움.</li>
<li><strong>테스트하기 좋게</strong>: 인터페이스만 보고 목(Mock)/페이크(Fake)를 끼워 넣기 쉬워짐.</li>
</ul>
<hr>
<h2 id="5-치트시트">5) 치트시트</h2>
<ul>
<li><p>싱글톤</p>
<ul>
<li>쉬운 길: <strong>모듈 전역 객체</strong></li>
<li>클래스로: <code>__new__</code> + <strong>Lock</strong> + <code>__init__</code> 가드</li>
</ul>
</li>
<li><p>추상 메서드</p>
<ul>
<li><code>from abc import ABC, abstractmethod</code></li>
<li><code>@property</code>와도 조합 가능 (추상 프로퍼티)</li>
<li>호출부는 <strong>인터페이스</strong>만 의존 → 확장 쉬움</li>
</ul>
</li>
</ul>
<hr>
<h2 id="6-체크리스트-바로-실습">6) 체크리스트 (바로 실습)</h2>
<ul>
<li><input disabled="" type="checkbox"> 모듈 전역 싱글톤으로 앱 설정 뚝딱 만들어보기</li>
<li><input disabled="" type="checkbox"> <code>__new__</code> 싱글톤에 Lock 추가하고 <code>id()</code>로 진짜 한 개인지 확인</li>
<li><input disabled="" type="checkbox"> 추상 클래스 하나 만들고 구현 클래스 2개 이상 작성</li>
<li><input disabled="" type="checkbox"> 결제/알림/스토리지 등 도메인으로 바꿔서 콤보 예제 돌려보기</li>
</ul>
<hr>
<p>읽어주셔서 감사합니다!
혹시 위 코드 복붙해서 돌려보다가 로그가 다르게 나온 부분 있으면, 어떤 환경/상황이었는지 댓글로 남겨주세요. 제가 재현해보고 글 업데이트할게요 :)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kaggle] Day-3. Child Mind Institute : EDA]]></title>
            <link>https://velog.io/@dev_brojean/Kaggle-Day-3.-Child-Mind-Institute-EDA</link>
            <guid>https://velog.io/@dev_brojean/Kaggle-Day-3.-Child-Mind-Institute-EDA</guid>
            <pubDate>Mon, 25 Nov 2024 12:47:05 GMT</pubDate>
            <description><![CDATA[<h1 id="🖥️-sii와-성별-및-나이대에-대한-데이터-분석-eda-과정">🖥️ SII와 성별 및 나이대에 대한 데이터 분석: EDA 과정</h1>
<p>이번 포스팅에서는 <strong>SII(Score Indicator Index)</strong>를 성별 및 나이대와 관련하여 분석한 과정을 정리합니다.<br>데이터 전처리 및 탐색적 데이터 분석(EDA)에 사용한 방법과 코드를 함께 다룹니다.</p>
<hr>
<h2 id="1️⃣-데이터-전처리-나이대를-범주형-변수로-변환">1️⃣ 데이터 전처리: 나이대를 범주형 변수로 변환</h2>
<h3 id="💡-작업-개요">💡 작업 개요</h3>
<ul>
<li>나이 데이터를 <strong>나이대(Age Group)</strong>로 변환하여 분석의 편의성을 높입니다.</li>
<li><code>pd.cut</code> 함수를 사용해 나이를 특정 구간으로 나누고, 그룹 라벨을 지정합니다.</li>
</ul>
<h3 id="📄-코드-예제">📄 코드 예제</h3>
<pre><code class="language-python">train[&#39;Age Group&#39;] = pd.cut(
    train[&#39;Basic_Demos-Age&#39;],
    bins=[4, 12, 18, 22],
    labels=[&#39;Children(5-12)&#39;, &#39;Adolescents(13-18)&#39;, &#39;Adults(19-22)&#39;]
)</code></pre>
<h3 id="🛠️-코드-설명">🛠️ 코드 설명</h3>
<ol>
<li><strong><code>pd.cut</code></strong>: 나이를 특정 구간으로 나누어 범주형 변수로 변환합니다.</li>
<li><strong><code>bins</code></strong>: 나이 구간의 경계값을 설정합니다:<ul>
<li><code>(4, 12]</code>: 4세 초과 ~ 12세 이하 → Children</li>
<li><code>(12, 18]</code>: 12세 초과 ~ 18세 이하 → Adolescents</li>
<li><code>(18, 22]</code>: 18세 초과 ~ 22세 이하 → Adults</li>
</ul>
</li>
<li><strong><code>labels</code></strong>: 각 구간에 대한 이름을 지정합니다.</li>
<li><strong>결과</strong>:<ul>
<li>새로운 열 <code>Age Group</code>이 생성되며, 나이에 따라 <code>Children(5-12)</code>, <code>Adolescents(13-18)</code>, <code>Adults(19-22)</code>로 분류됩니다.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="2️⃣-그룹화와-빈도-분석">2️⃣ 그룹화와 빈도 분석</h2>
<h3 id="💡-작업-개요-1">💡 작업 개요</h3>
<ul>
<li><strong>SII</strong>, <strong>성별</strong>, <strong>나이대</strong>의 관계를 분석하기 위해 데이터를 그룹화하여 빈도를 계산합니다.</li>
<li>이를 통해 각 그룹 간의 분포를 파악합니다.</li>
</ul>
<h3 id="📄-코드-예제-1">📄 코드 예제</h3>
<pre><code class="language-python">stats = train.groupby([&#39;Age Group&#39;, &#39;Basic_Demos-Sex&#39;, &#39;sii&#39;]).size().unstack(fill_value=0)</code></pre>
<h3 id="🛠️-코드-설명-1">🛠️ 코드 설명</h3>
<ol>
<li><strong><code>groupby([&#39;Age Group&#39;, &#39;Basic_Demos-Sex&#39;, &#39;sii&#39;])</code></strong>:<ul>
<li><code>Age Group</code>, <code>성별(Basic_Demos-Sex)</code>, 그리고 <code>SII</code>를 기준으로 데이터를 그룹화합니다.</li>
</ul>
</li>
<li><strong><code>.size()</code></strong>:<ul>
<li>각 그룹의 행 개수(빈도)를 계산합니다.</li>
</ul>
</li>
<li><strong><code>.unstack(fill_value=0)</code></strong>:<ul>
<li><code>sii</code>를 열로 이동하여 <strong>2차원 테이블</strong>로 변환.</li>
<li>결측값(NaN)은 <strong>0</strong>으로 채웁니다.</li>
</ul>
</li>
<li><strong>결과 예시</strong>:<pre><code class="language-plaintext">sii                        0    1    2
Age Group       Sex                       
Children(5-12)  Male       5    3    1
                Female     4    2    0
Adolescents(13-18) Male    6    2    1
                   Female  3    1    0</code></pre>
</li>
</ol>
<hr>
<h2 id="3️⃣-각-그룹의-비율-계산">3️⃣ 각 그룹의 비율 계산</h2>
<h3 id="💡-작업-개요-2">💡 작업 개요</h3>
<ul>
<li>각 나이대와 성별에서 <code>SII</code>의 비율을 계산하여 비교.</li>
<li>그룹별 데이터를 퍼센트(%)로 변환해 가독성을 높입니다.</li>
</ul>
<h3 id="📄-코드-예제-2">📄 코드 예제</h3>
<pre><code class="language-python">stats_prop = stats.div(stats.sum(axis=1), axis=0) * 100</code></pre>
<h3 id="🛠️-코드-설명-2">🛠️ 코드 설명</h3>
<ol>
<li><strong><code>stats.sum(axis=1)</code></strong>:<ul>
<li>각 행(나이대 및 성별 그룹)의 총합(빈도)을 계산.</li>
</ul>
</li>
<li><strong><code>.div(..., axis=0)</code></strong>:<ul>
<li>각 그룹의 빈도를 총합으로 나눠 비율을 계산.</li>
</ul>
</li>
<li><strong><code>* 100</code></strong>:<ul>
<li>비율을 퍼센트(%)로 변환.</li>
</ul>
</li>
<li><strong>결과 예시</strong>:<pre><code class="language-plaintext">sii                        0        1        2
Age Group       Sex                       
Children(5-12)  Male     55.6     33.3     11.1
                Female   66.7     33.3      0.0
Adolescents(13-18) Male  66.7     22.2     11.1
                   Female 75.0     25.0      0.0</code></pre>
</li>
</ol>
<hr>
<h2 id="4️⃣-데이터-검증">4️⃣ 데이터 검증</h2>
<h3 id="💡-작업-개요-3">💡 작업 개요</h3>
<ul>
<li>데이터 분석 전에 <code>SII</code>, <code>성별</code>, <code>나이</code> 등의 열에 결측값이 없는지 검증합니다.</li>
<li>결측값이 있으면 분석 과정에서 오류가 발생할 수 있으므로 사전에 검증이 필요합니다.</li>
</ul>
<h3 id="📄-코드-예제-3">📄 코드 예제</h3>
<pre><code class="language-python">assert train[&#39;Basic_Demos-Age&#39;].isna().sum() == 0, &quot;Age 열에 결측값이 있습니다!&quot;
assert train[&#39;Basic_Demos-Sex&#39;].isna().sum() == 0, &quot;Sex 열에 결측값이 있습니다!&quot;
assert train[&#39;sii&#39;].isna().sum() == 0, &quot;SII 열에 결측값이 있습니다!&quot;</code></pre>
<h3 id="🛠️-코드-설명-3">🛠️ 코드 설명</h3>
<ol>
<li><strong><code>isna().sum()</code></strong>:<ul>
<li>각 열에서 결측값(<code>NaN</code>)의 개수를 계산합니다.</li>
</ul>
</li>
<li><strong><code>assert</code></strong>:<ul>
<li>특정 조건(결측값 개수 == 0)이 참인지 확인.</li>
<li>조건이 거짓이면 <code>AssertionError</code>를 발생시켜 실행 중단.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="5️⃣-eda-결과-요약">5️⃣ EDA 결과 요약</h2>
<h3 id="1-sii와-나이대-성별의-분포">1. <strong>SII와 나이대, 성별의 분포</strong></h3>
<ul>
<li><code>Children(5-12)</code> 그룹:<ul>
<li><strong>남성</strong>에서 <code>SII=0</code>이 가장 많고, <code>SII=2</code>는 상대적으로 적음.</li>
<li><strong>여성</strong>은 <code>SII=0</code>의 비율이 더 높음.</li>
</ul>
</li>
<li><code>Adolescents(13-18)</code> 그룹:<ul>
<li><strong>남성</strong>에서 <code>SII=0</code>과 <code>SII=1</code>이 주로 나타남.</li>
<li><strong>여성</strong>은 <code>SII=0</code>이 대부분을 차지.</li>
</ul>
</li>
</ul>
<h3 id="2-비율-차이">2. <strong>비율(%) 차이</strong></h3>
<ul>
<li>전체적으로 나이가 어릴수록 <code>SII=0</code>의 비율이 높고, 나이가 많아질수록 <code>SII=1</code> 또는 <code>SII=2</code>로 이동하는 경향이 있음.</li>
<li>성별 간 차이:<ul>
<li>남성이 여성보다 높은 <code>SII</code>를 가지는 경우가 많음.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="🔍-결론">🔍 결론</h2>
<p>EDA를 통해 <strong>SII, 성별, 나이대</strong> 간의 관계를 시각화하고 통계적으로 분석할 수 있었습니다.<br>분석 결과를 바탕으로 다음 단계에서는:</p>
<ol>
<li><strong>SII의 주요 요인</strong>을 더 깊이 이해.</li>
<li>모델 학습 시 나이대 및 성별에 따른 <strong>특화된 학습 전략</strong>을 적용.</li>
</ol>
<p>데이터 분석은 이해를 높이고, 더 나은 모델 학습을 위한 기반을 마련하는 과정입니다. 😊<br>다음 포스팅에서는 시각화를 통해 데이터를 더 직관적으로 표현해보겠습니다. 🚀
피드백은 언제나 환영입니다!!</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HardWare] GPU 서버 필수 요소]]></title>
            <link>https://velog.io/@dev_brojean/HardWare-GPU-%EC%84%9C%EB%B2%84-%ED%95%84%EC%88%98-%EC%9A%94%EC%86%8C</link>
            <guid>https://velog.io/@dev_brojean/HardWare-GPU-%EC%84%9C%EB%B2%84-%ED%95%84%EC%88%98-%EC%9A%94%EC%86%8C</guid>
            <pubDate>Sun, 17 Nov 2024 11:00:36 GMT</pubDate>
            <description><![CDATA[<h1 id="gpu-하드웨어-스펙-알아보기-🖥️">GPU 하드웨어 스펙 알아보기 🖥️</h1>
<p>이번에는 GPU 하드웨어와 학습 방식에 대해 간단히 정리해보았습니다. 아직 초기 단계라 구체적인 사양과 최적화 방법은 더 알아볼 계획이며, 추후 하드웨어 구성과 학습 전략도 세부적으로 정리할 예정입니다.</p>
<hr>
<h2 id="💡-메인보드와-gpu-구성">💡 메인보드와 GPU 구성</h2>
<ul>
<li>현재 <strong>메인보드(마더보드)</strong>는 <strong>PCI 슬롯 4개</strong>를 사용하여 GPU 4장을 장착할 수 있는 구조로 구성될 예정입니다.</li>
<li>이런 하드웨어 기반에서 GPU 학습 환경을 어떻게 최적화할지 고민 중입니다.</li>
</ul>
<hr>
<h2 id="💡-학습-방식-정리">💡 학습 방식 정리</h2>
<ol>
<li><p><strong>H100 사용과 Fine-Tuning</strong>  </p>
<ul>
<li>H100 GPU는 대규모 모델 학습에 적합하며, 특히 <strong>풀파인튜닝(Fine-Tuning)</strong> 과정이 필수적입니다.  </li>
<li>단일 학습이 아닌 병렬 학습을 고려하고 있습니다.</li>
</ul>
</li>
<li><p><strong>FSDP (Fully Sharded Data Parallel)</strong>  </p>
<ul>
<li><strong>직렬 처리 방식</strong>으로, 데이터를 순차적으로 학습합니다.  </li>
<li>한 GPU에서 처리 후 남은 데이터를 다음 GPU가 이어받아 학습하는 구조입니다.</li>
</ul>
</li>
<li><p><strong>DDP (Distributed Data Parallel)</strong>  </p>
<ul>
<li><strong>병렬 처리 방식</strong>으로, 각 GPU에서 독립적으로 데이터를 학습하고 결과(weight)를 동기화합니다.  </li>
<li>병렬 학습으로 속도를 높이는 데 효과적입니다.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="💡-gpu-간-통신-방식">💡 GPU 간 통신 방식</h2>
<ul>
<li><strong>브릿지</strong>를 통해 GPU 간 통신이 이루어지며, 통신 방식에 따라 성능 차이가 발생합니다.<ul>
<li><strong>P2P(Point-to-Point)</strong>: 순차적 통신으로, GPU 간 데이터를 CPU를 통해 전송.  </li>
<li><strong>NVLink</strong>: GPU 간 고속 통신을 지원하여 더 빠른 데이터 전송 가능.</li>
</ul>
</li>
</ul>
<h3 id="통신-방식의-흐름">통신 방식의 흐름</h3>
<ul>
<li><strong>P2P 방식</strong>: 데이터 → 브릿지 → GPU → 브릿지 → CPU → 브릿지 → GPU → 추론.</li>
<li><strong>NVLink 방식</strong>: 데이터 → 브릿지 → GPU → 브릿지 → GPU → 추론.</li>
</ul>
<hr>
<h2 id="💡-nvlink-지원-여부와-정책">💡 NVLink 지원 여부와 정책</h2>
<p>NVLink는 초기 GPU 모델에서는 일반적으로 제공되었지만, 이후 모델에서 지원이 제한되었다가 최근 H100과 같은 고급 GPU에서는 다시 제공되고 있습니다.<br>현재 관심 있는 GPU 모델들의 NVLink 지원 여부는 다음과 같습니다:</p>
<table>
<thead>
<tr>
<th>GPU 모델</th>
<th>NVLink 지원 여부</th>
</tr>
</thead>
<tbody><tr>
<td><strong>RTX 3090</strong></td>
<td>✅ 지원</td>
</tr>
<tr>
<td><strong>RTX A100</strong></td>
<td>✅ 지원</td>
</tr>
<tr>
<td><strong>RTX 4090</strong></td>
<td>❌ 미지원</td>
</tr>
<tr>
<td><strong>RTX 6000 ADA</strong></td>
<td>❌ 미지원</td>
</tr>
<tr>
<td><strong>H100</strong></td>
<td>✅ NVLink 제공</td>
</tr>
</tbody></table>
<h3 id="nvlink-지원-정책에-대한-생각">NVLink 지원 정책에 대한 생각</h3>
<p>Nvidia는 RTX 30 시리즈(예: RTX 3090)에서 NVLink를 제공했지만, RTX 40 시리즈와 같은 이후 제품에서는 이를 제거했는데, 이후 H100과 같은 고급 GPU에서 다시 NVLink를 제공하며, NVLink가 고가 제품에만 제한적으로 제공되는 <strong>상업적 전략</strong>을 보인다 생각해요.</p>
<p>일반 사용자를 배제하고 고성능 GPU 시장에서 수익을 극대화하려는 Nvidia의 정책은 많은 비판을 받고 있습니다. 특히 RTX 40 시리즈와 같은 최신 모델에서 NVLink를 제거한 뒤 다시 특정 제품군에만 도입한 점은 Nvidia의 <strong>독점적 상술</strong>을 잘 보여주는거 같습니다.</p>
<hr>
<h3 id="앞으로의-계획">앞으로의 계획</h3>
<ul>
<li>아직 초기 단계라 대략적인 학습 방식과 GPU 구성만 정리했습니다.</li>
<li>앞으로는 구체적으로 <strong>하드웨어 스펙</strong>과 <strong>효율적인 학습 전략</strong>을 함께 정리할 계획입니다.  </li>
<li>특히 NVLink와 같은 기술을 활용한 GPU 간 통신 최적화와, 이를 대체할 수 있는 방법도 연구할 예정입니다.</li>
<li>하드웨어 구성, 통신 방식, 학습 알고리즘을 최적화하여 성능을 극대화할 방법을 탐구해 나가겠습니다. 😊</li>
</ul>
<hr>
<p><strong>한 걸음씩 알아가는 과정 중이며 피드백은 언제나 환영입니다. 앞으로 더 나은 정리를 위해 노력하겠습니다!</strong> 🚀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Kaggle] Day-2. Child Mind Institute : EDA]]></title>
            <link>https://velog.io/@dev_brojean/Kaggle-Day-2.-Child-Mind-Institute-EDA</link>
            <guid>https://velog.io/@dev_brojean/Kaggle-Day-2.-Child-Mind-Institute-EDA</guid>
            <pubDate>Sun, 17 Nov 2024 08:55:50 GMT</pubDate>
            <description><![CDATA[<h1 id="eda-데이터-전처리-및-sii-재계산-🛠️">EDA: 데이터 전처리 및 SII 재계산 🛠️</h1>
<p>이번 EDA 과정에서는 <strong>PCIAT 데이터의 결측치 처리 및 SII 점수 재계산</strong>을 수행하였습니다. 이후 결과를 바탕으로 데이터의 이상값을 분석하고 시각화하는 과정까지 진행했습니다.</p>
<hr>
<h2 id="1-pciat-pciat_total-검증-및-합계-재계산-🧮">1. PCIAT-PCIAT_Total 검증 및 합계 재계산 🧮</h2>
<pre><code class="language-python">PCIAT_cols = [f&#39;PCIAT-PCIAT_{i+1:02d}&#39; for i in range(20)]

recalc_total_score = train_with_sii[PCIAT_cols].sum(
    axis=1, skipna=True
)

(recalc_total_score == train_with_sii[&#39;PCIAT-PCIAT_Total&#39;]).all() # PCIAT Valuse Sum == Total</code></pre>
<h3 id="설명">설명</h3>
<ul>
<li><code>PCIAT_cols</code>: 각 질문 열 이름을 동적으로 생성합니다.</li>
<li><code>sum(axis=1, skipna=True)</code>: 결측치(<code>NaN</code>)를 무시하고 각 행의 합계를 계산합니다.</li>
<li><code>all()</code>: 합계가 <code>PCIAT-PCIAT_Total</code>과 동일한지 전체적으로 확인합니다.</li>
</ul>
<h3 id="결과">결과</h3>
<p>합계가 동일한지를 확인하여, 데이터의 정합성을 검증할 수 있습니다. 이후 이 정보를 바탕으로 SII 값을 재계산하였습니다.</p>
<hr>
<h2 id="2-sii-재계산-함수-정의-및-적용-🛠️">2. SII 재계산 함수 정의 및 적용 🛠️</h2>
<pre><code class="language-python">def recalculate_sii(row):
    # PCIAT-PCIAT_Total 값이 결측치인 경우 NaN 반환
    if pd.isna(row[&#39;PCIAT-PCIAT_Total&#39;]):
        return np.nan, np.nan

    # 최대 가능한 점수 계산
    max_possible = row[&#39;PCIAT-PCIAT_Total&#39;] + row[PCIAT_cols].isna().sum() * 5

    # 디버깅용 출력 (필요 없으면 제거 가능)
    print(f&quot;PCIAT-PCIAT_Total: {row[&#39;PCIAT-PCIAT_Total&#39;]}&quot;)
    print(f&quot;Missing questions: {row[PCIAT_cols].isna().sum()}&quot;)
    print(f&quot;Added to max_possible: {row[PCIAT_cols].isna().sum() * 5}&quot;)
    print(&#39;-&#39; * 80)

    # SII 카테고리 재계산
    if row[&#39;PCIAT-PCIAT_Total&#39;] &lt;= 30 and max_possible &lt;= 30:
        return max_possible, 0
    elif 31 &lt;= row[&#39;PCIAT-PCIAT_Total&#39;] &lt;= 49 and max_possible &lt;= 49:
        return max_possible, 1
    elif 50 &lt;= row[&#39;PCIAT-PCIAT_Total&#39;] &lt;= 79 and max_possible &lt;= 79:
        return max_possible, 2
    elif row[&#39;PCIAT-PCIAT_Total&#39;] &gt;= 80 and max_possible &gt;= 80:
        return max_possible, 3

    # 범위에 해당하지 않을 경우
    return max_possible, np.nan

# train 데이터프레임에 함수 적용
train[[&#39;recalc_total&#39;, &#39;recalc_sii&#39;]] = train.apply(
    recalculate_sii, axis=1, result_type=&#39;expand&#39;
)</code></pre>
<h3 id="설명-1">설명</h3>
<ul>
<li>결측치를 포함한 최대 점수를 계산하여 <strong>SII 카테고리를 재분류</strong>합니다.</li>
<li><code>apply()</code>를 통해 각 행에 대해 <code>recalculate_sii()</code> 함수를 적용합니다.</li>
<li>결과적으로 <strong>재계산된 총점(<code>recalc_total</code>)</strong>과 <strong>재분류된 SII(<code>recalc_sii</code>)</strong>를 데이터프레임에 추가합니다.</li>
</ul>
<hr>
<h2 id="3-이상-행mismatch-rows-분석-🔍">3. 이상 행(Mismatch Rows) 분석 🔍</h2>
<pre><code class="language-python">mismatch_rows = train[
    (train[&#39;recalc_sii&#39;] != train[&#39;sii&#39;]) &amp; train[&#39;sii&#39;].notna()
]

mismatch_rows[PCIAT_cols + [
    &#39;PCIAT-PCIAT_Total&#39;, &#39;sii&#39;, &#39;recalc_sii&#39;
]].style.applymap(
    lambda x: &#39;background-color: #FFC0CB&#39; if pd.isna(x) else &#39;&#39;
)</code></pre>
<h3 id="설명-2">설명</h3>
<ul>
<li><strong>Mismatch Rows</strong>: 기존 <code>sii</code>와 재계산된 <code>recalc_sii</code>가 일치하지 않는 행을 필터링합니다.</li>
<li><code>style.applymap()</code>: 결측치(<code>NaN</code>)가 있는 셀에 배경색(핑크색)을 추가하여 직관적으로 확인할 수 있도록 합니다.</li>
</ul>
<hr>
<h2 id="4-데이터-정제-및-시각화-🎨">4. 데이터 정제 및 시각화 🎨</h2>
<h3 id="데이터-정제">데이터 정제</h3>
<pre><code class="language-python"># 기존 SII 값을 재계산 값으로 교체
train[&#39;sii&#39;] = train[&#39;recalc_sii&#39;]

# 완전한 응답의 총합만 유지, 결측치가 있으면 NaN으로 설정
train[&#39;complete_resp_total&#39;] = train[&#39;PCIAT-PCIAT_Total&#39;].where(
    train[PCIAT_cols].notna().all(axis=1), np.nan
)

# SII 범주화 및 순서 지정
sii_map = {0: &#39;0 (None)&#39;, 1: &#39;1 (Mild)&#39;, 2: &#39;2 (Moderate)&#39;, 3: &#39;3 (Severe)&#39;}
train[&#39;sii&#39;] = train[&#39;sii&#39;].map(sii_map).fillna(&#39;Missing&#39;)
sii_order = [&#39;Missing&#39;, &#39;0 (None)&#39;, &#39;1 (Mild)&#39;, &#39;2 (Moderate)&#39;, &#39;3 (Severe)&#39;]
train[&#39;sii&#39;] = pd.Categorical(train[&#39;sii&#39;], categories=sii_order, ordered=True)

# 불필요한 열 삭제
train.drop(columns=&#39;recalc_sii&#39;, inplace=True)</code></pre>
<h3 id="시각화">시각화</h3>
<pre><code class="language-python">sii_counts = train[&#39;sii&#39;].value_counts().reset_index()
total = sii_counts[&#39;count&#39;].sum()
sii_counts[&#39;percentage&#39;] = (sii_counts[&#39;count&#39;] / total) * 100

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# SII 분포 시각화
sns.barplot(x=&#39;sii&#39;, y=&#39;count&#39;, data=sii_counts, palette=&#39;Blues_d&#39;, ax=axes[0])
axes[0].set_title(&#39;Distribution of Severity Impairment Index (sii)&#39;, fontsize=14)
for p in axes[0].patches:
    height = p.get_height()
    percentage = sii_counts.loc[sii_counts[&#39;count&#39;] == height, &#39;percentage&#39;].values[0]
    axes[0].text(
        p.get_x() + p.get_width() / 2,
        height + 5, f&#39;{int(height)} ({percentage:.1f}%)&#39;,
        ha=&quot;center&quot;, fontsize=12
    )

# PCIAT_Total 분포 시각화
sns.histplot(train[&#39;complete_resp_total&#39;].dropna(), bins=20, ax=axes[1])
axes[1].set_title(&#39;Distribution of PCIAT_Total&#39;, fontsize=14)
axes[1].set_xlabel(&#39;PCIAT_Total for Complete PCIAT Responses&#39;)

plt.tight_layout()
plt.show()</code></pre>
<h3 id="설명-3">설명</h3>
<ul>
<li><strong>SII 분포 시각화</strong>: 각 SII 수준별 분포를 막대 그래프로 나타내고, 각 카테고리의 비율(%)을 표시합니다.</li>
<li><strong>PCIAT_Total 분포 시각화</strong>: 완전한 응답(<code>complete_resp_total</code>)에 대해 점수 분포를 히스토그램으로 표시합니다.</li>
</ul>
<hr>
<h2 id="주요-결과-📋">주요 결과 📋</h2>
<ol>
<li><strong>SII 재계산</strong>: 데이터 결측치를 고려한 점수 재계산 및 SII 분류 결과를 확인했습니다.</li>
<li><strong>이상 행 식별</strong>: 기존 SII 값과 불일치하는 행을 추출하여 검토하였습니다.</li>
<li><strong>시각화</strong>: SII와 PCIAT_Total의 분포를 시각화하여 데이터를 더 직관적으로 이해할 수 있도록 정리하였습니다.</li>
</ol>
<hr>
<h2 id="ps-🤔">P.S 🤔</h2>
<p>데이터 컬럼이 너무 많아서 분석할 내용이 많다 보니 하나씩 공부해가는 과정이라 EDA 작업이 늦어지고 있네요,,,<br>다음 글에서는 다른 컬럼들의 정보를 바탕으로 추가적인 EDA를 진행해볼게요. 🚀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Recommendation System] 추천시스템①]]></title>
            <link>https://velog.io/@dev_brojean/Recommendation-System-%EC%B6%94%EC%B2%9C%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@dev_brojean/Recommendation-System-%EC%B6%94%EC%B2%9C%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Mon, 11 Nov 2024 14:03:20 GMT</pubDate>
            <description><![CDATA[<p>이번 게시물의 주제는 <strong>추천 시스템</strong>입니다. 😊</p>
<hr>
<h2 id="1-추천-시스템이란-🤔">1. 추천 시스템이란? 🤔</h2>
<p><strong>추천 시스템</strong>은 특정 시점에 특정 고객에게 특정한 상품을 추천하는 시스템입니다.<br>E-commerce, OTT 등 다양한 서비스에서 <strong>상품 구매 및 선호도에 대한 사용자의 피드백</strong>(예: 평점, 후기 등)을 바탕으로 아이템을 추천하는 것이 추천 시스템의 기본 아이디어입니다.</p>
<p>추천 시스템의 발전을 간략히 살펴보면, 초기에는 단순한 <strong>연관 상품 추천 방식</strong>에서 시작되었습니다. 이후 넷플릭스에서 데이터를 활용한 추천 시스템 대회를 열었고, 이때 <strong>SVD(Singular Value Decomposition)</strong> 방식을 기반으로 한 <strong>협업 필터링</strong> 모델이 우승하면서 추천 시스템 연구가 활발해졌습니다. 현재는 <strong>FM 모델(Factorization Machine)</strong>, <strong>강화 학습</strong>, <strong>딥러닝</strong>을 이용하고, 최근 뉴런 기반의 추천시스템과 그래프 기반의 추천시스템 등 추천 시스템의 기술은 지속적으로 발전하여 초개인화 추천시스템으로 발전하고 있습니다. 🔍</p>
<hr>
<h2 id="2-추천-시스템의-종류-🧩">2. 추천 시스템의 종류 🧩</h2>
<h3 id="content-based-recommender-system-콘텐츠-기반-추천-시스템">Content-Based Recommender System (콘텐츠 기반 추천 시스템)</h3>
<p>콘텐츠 기반 추천 시스템은 <strong>아이템의 세부 정보를 기반으로</strong> 사용자가 과거에 소비한 콘텐츠와 유사한 콘텐츠를 추천하는 방식입니다.<br>여기서 콘텐츠란 아이템의 성질이나 특성을 의미하며, 보통 <strong>텍스트</strong>로 이루어진 정보가 많이 사용됩니다. 이를 벡터화하여 유사도를 계산합니다.</p>
<h4 id="장점-👍">장점 👍</h4>
<ul>
<li><strong>신규 사용자에게도 추천 가능</strong>: 다른 사용자의 데이터가 없어도 됩니다.</li>
<li><strong>추천의 근거를 제공</strong>: 어떤 콘텐츠를 추천하는지 설명이 가능합니다.</li>
<li><strong>새로운 콘텐츠 추천</strong>: 기존에 유명하지 않거나 새로 추가된 콘텐츠도 추천 가능.</li>
</ul>
<h4 id="단점-👎">단점 👎</h4>
<ul>
<li><strong>흥미 기반의 제한</strong>: 사용자가 과거에 흥미를 보인 콘텐츠가 없으면 추천이 어렵습니다.</li>
<li><strong>유사 콘텐츠만 추천</strong>: 이미 알고 있는 콘텐츠와 비슷한 것만 추천하는 경향이 있습니다.</li>
</ul>
<hr>
<h3 id="collaborative-filtering-협업-필터링-👥">Collaborative Filtering (협업 필터링) 👥</h3>
<p><strong>협업 필터링</strong>은 많은 사용자의 구매 패턴이나 평점을 바탕으로 다른 사용자에게 콘텐츠를 추천하는 방식입니다.<br>주된 가정은 &quot;비슷한 취향을 가진 사용자에게 비슷한 콘텐츠를 추천한다&quot;는 것입니다. 사용자 행동 데이터를 기반으로, 크게 두 가지 방식이 있습니다: <strong>메모리 기반 알고리즘</strong>과 <strong>모델 기반 알고리즘</strong>입니다.</p>
<h4 id="1-memory-based-algorithm-🔄">1) Memory-Based Algorithm 🔄</h4>
<p>메모리 기반 협업 필터링은 <strong>사용자 간, 혹은 아이템 간의 유사도를 계산하여</strong> 추천하는 전통적인 방식입니다.  </p>
<ul>
<li><strong>User-Based (사용자 기반)</strong>: 유사한 취향을 가진 사용자가 선호하는 콘텐츠를 추천</li>
<li><strong>Item-Based (아이템 기반)</strong>: 유사한 아이템을 바탕으로 콘텐츠를 추천</li>
</ul>
<p>장점은 <strong>쉽게 구현 가능</strong>하고, <strong>결과를 쉽게 해석</strong>할 수 있다는 점입니다.</p>
<h4 id="2-model-based-algorithm-💡">2) Model-Based Algorithm 💡</h4>
<p>모델 기반 협업 필터링은 <strong>잠재 요인(Latent Factor)을 추출하여</strong> 추천하는 방식으로, <strong>행렬 분해(Matrix Factorization)</strong>를 통해 잠재 요인을 추출해 추천을 합니다.<br>이 방식은 <strong>예측 속도가 빠르며</strong>, 대규모 데이터에도 효율적입니다. 하지만 추천의 <strong>설명력이 부족</strong>하며, 예측 정확도를 높이기 위해서는 모델의 튜닝이 필요합니다.</p>
<hr>
<h3 id="hybrid-model-하이브리드-추천-시스템-⚙️">Hybrid Model (하이브리드 추천 시스템) ⚙️</h3>
<p>하이브리드 추천 시스템은 <strong>Content-Based와 Collaborative Filtering 방식을 결합</strong>하여 두 방식의 단점을 보완하는 방식입니다. 다양한 알고리즘을 함께 사용하여 <strong>추천의 정확도</strong>와 <strong>추천 범위</strong>를 넓히고 있습니다. 💪</p>
<hr>
<h2 id="마치며-📝">마치며 📝</h2>
<p>이번 글에서는 추천 시스템의 기본 개념과 주요 알고리즘의 종류에 대해 간략히 알아보았습니다.<br>아직 공부하는 단계에서 작성한 내용이라 부족할 수 있지만, 앞으로 추천 시스템에 대해 하나씩 더 깊이 있게 다뤄볼 예정입니다!😊</p>
<p>잘못된 내용이나 피드백은 언제나 환영입니다~!!</p>
]]></description>
        </item>
    </channel>
</rss>