<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Diffusion on dirac042</title><link>https://dirac042.github.io/tags/diffusion/</link><description>dirac042's journal — notes on mathematics, computer science and building things.</description><generator>Hugo</generator><language>ko-kr</language><managingEditor>dirac042</managingEditor><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Thu, 13 Aug 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://dirac042.github.io/tags/diffusion/index.xml" rel="self" type="application/rss+xml"/><item><title>Magnitude Scaling Technique — SGMSE의 Amplitude Transformation</title><link>https://dirac042.github.io/posts/magnitude-scaling-technique/</link><pubDate>Thu, 13 Aug 2026 00:00:00 +0900</pubDate><guid>https://dirac042.github.io/posts/magnitude-scaling-technique/</guid><category>Audio</category><category>Diffusion</category><category>Speech Enhancement</category><description>복소 STFT(cSTFT) 위에서 Diffusion을 돌릴 때, 유난히 큰 스펙트럼 피크 때문에 학습이 흔들리는 문제를 어떻게 다루는지에 대한 짧은 정리. SGMSE 논문(Richter, Welker, Lemercier, Lay, Gerkmann, Speech Enhancement and Dereverberation with Diffusion-based Generative Models, IEEE/ACM TASLP 2023)에서 처음 사용한 기법이다.</description><content:encoded>&lt;p>복소 STFT(cSTFT) 위에서 Diffusion을 돌릴 때, 유난히 큰 스펙트럼 피크 때문에 학습이 흔들리는 문제를 어떻게 다루는지에 대한 짧은 정리.&lt;/p>
&lt;p>&lt;a href="https://arxiv.org/abs/2208.05830" target="_blank" rel="noopener noreferrer">&lt;strong>SGMSE&lt;/strong>&lt;/a> 논문(Richter, Welker, Lemercier, Lay, Gerkmann, &lt;em>Speech Enhancement and Dereverberation with Diffusion-based Generative Models&lt;/em>, IEEE/ACM TASLP 2023)에서 처음 사용한 기법이다.&lt;/p>
&lt;p>논문에서는 Amplitude Transformation이라는 단어로 표현한다.&lt;/p>
&lt;ul>
&lt;li>STFT에서 만들어지는 Complex Coefficient를 그대로 사용하되,&lt;/li>
&lt;li>Phase는 유지하고, Magnitude를 Power-Law로 압축해 전체 Scale을 줄이자.&lt;/li>
&lt;/ul>
&lt;figure class="post-figure">
&lt;img src="https://dirac042.github.io/images/fig-amplitude-compression.png" alt="Image Description" loading="lazy" decoding="async">
&lt;/figure>&lt;blockquote>
&lt;p>같은 신호의 |c|(왼쪽)와 β|c|^α(가운데). 크게 울리는 배음 몇 개가 화면을 독차지하던 것이, 압축 뒤에는 조용한 마찰음 덩어리와 희미한 상승음까지 보인다. 오른쪽은 α에 따른 압축 곡선.&lt;/p>
&lt;/blockquote>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>SGMSE의 Task: Speech Enhancement/Dereverberation을 cSTFT 도메인에서 수행.&lt;/p>
&lt;ul>
&lt;li>Pred: Clean Speech의 Real/Imaginary Spectrogram
&lt;ul>
&lt;li>왜? Magnitude-only Domain에서는 Diffusion Process가 어색해진다.&lt;/li>
&lt;li>Magnitude는 음수가 될 수 없음 → Gaussian Noise를 더하면 음수값의 Amplitude가 나옴.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;aside class="callout callout-note">
&lt;p class="callout-title">배경: 왜 하필 cSTFT인가&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>Diffusion은 &amp;ldquo;데이터에 가우시안 노이즈를 더했다가 되돌리는&amp;rdquo; 과정이라, 데이터가 실수 전체(음수 포함)에 자연스럽게 퍼져 있어야 한다. 크기(magnitude)만 쓰면 항상 0 이상이라 노이즈를 더하는 순간 정의역을 벗어나고, 위상은 따로 복원해야 한다. 실수부/허수부로 나눈 cSTFT는 두 채널이 모두 실수라 이 문제가 없다. 논문 세팅은 16 kHz, window 510(주파수 빈 256개), hop 128(75% 겹침), periodic Hann.&lt;/p>
&lt;/div>
&lt;/aside>&lt;h2 id="amplitude-transformation">Amplitude Transformation&lt;/h2>
&lt;p>cSTFT Coefficient는 다음과 같이 정의된다:&lt;br>
&lt;/p>
&lt;div class="math math-block">\[c=|c|e^{i\angle c}\]&lt;/div>&lt;p>&lt;br>
이때, &lt;span class="math math-inline">\(|c|\)&lt;/span>는 Magnitude, &lt;span class="math math-inline">\(\angle c\)&lt;/span>는 Phase다.&lt;/p>
&lt;p>SGMSE는 위의 Coefficient를 다음과 같이 변환한다.&lt;br>
&lt;/p>
&lt;div class="math math-block">\[\tilde{c}=\beta |c|^{\alpha}e^{i\angle c}\]&lt;/div>&lt;ul>
&lt;li>&lt;span class="math math-inline">\(\alpha \in (0,1]\)&lt;/span> : Magnitude Compression Exponent&lt;/li>
&lt;li>&lt;span class="math math-inline">\(\beta &amp;gt; 0\)&lt;/span> : Scale Factor&lt;/li>
&lt;/ul>
&lt;p>위를 자세히 보면, Phase, 그리고 Complex Direction은 전혀 바뀌지 않았고, Magnitude에만 Scaling이 가해졌다.&lt;/p>
&lt;p>논문이 실험적으로 고른 값은 &lt;span class="math math-inline">\(\alpha=0.5\)&lt;/span>, &lt;span class="math math-inline">\(\beta=0.15\)&lt;/span>다. 숫자로 감을 잡아보면: 어떤 빈의 크기가 100이고 다른 빈이 1이라면 원래는 100배 차이지만, &lt;span class="math math-inline">\(\alpha=0.5\)&lt;/span>를 거치면 &lt;span class="math math-inline">\(0.15\times10=1.5\)&lt;/span> 대 &lt;span class="math math-inline">\(0.15\times1=0.15\)&lt;/span>, 즉 &lt;strong>10배&lt;/strong> 차이로 줄어든다. 큰 놈은 많이, 작은 놈은 조금 눌리는 것이 power-law 압축의 성질이다. 논문의 표현을 빌리면, α는 &amp;ldquo;에너지가 낮은 주파수 성분(예: 무성음의 마찰음)을 끌어올리는&amp;rdquo; 역할이고, β는 전체 크기를 diffusion 노이즈 스케일에 맞추는 정규화 역할이다.&lt;/p>
&lt;h2 id="inverse-amplitude-transformation">Inverse Amplitude Transformation&lt;/h2>
&lt;p>위의 Representation은 역변환도 간단하다.&lt;br>
&lt;/p>
&lt;div class="math math-block">\[c=\left(\frac{|\tilde{c}|}{\beta}\right)^{\frac{1}{\alpha}}e^{i\angle \tilde{c}}\]&lt;/div>&lt;p>주의할 점 하나: 역변환은 &lt;span class="math math-inline">\(1/\alpha\)&lt;/span> 제곱이라 &lt;strong>압축된 도메인에서의 작은 오차가 원래 도메인에서는 증폭&lt;/strong>된다. &lt;span class="math math-inline">\(\alpha\)&lt;/span>를 너무 작게 잡으면 큰 성분의 오차가 커지는 이유다. 0.5는 그 사이의 타협점.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">compress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">alpha&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">beta&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.15&lt;/span>&lt;span class="p">):&lt;/span> &lt;span class="c1"># c: complex STFT (F, T)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">beta&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">abs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="n">alpha&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="n">j&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">angle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">decompress&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c_tilde&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">alpha&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">beta&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.15&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">abs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c_tilde&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">beta&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">alpha&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="n">j&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">angle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c_tilde&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="효과">효과&lt;/h2>
&lt;ol>
&lt;li>너무 큰 Spectral Peak가 지배적이지 않게 만들 수 있다.&lt;/li>
&lt;li>Low-Energy의 Speech 성분이 부각되어 숨소리 같은 소리가 잘 보존된다.&lt;/li>
&lt;li>원래 Diffusion의 Noise Scale에서 어긋나지 않는다.&lt;/li>
&lt;li>Extreme Magnitude가 덜 나와서 학습이 안정적이다.&lt;/li>
&lt;li>Perceptual Relevance가 증가한다. (결과물이 더 그럴싸해진다.)&lt;/li>
&lt;/ol>
&lt;aside class="callout callout-note">
&lt;p class="callout-title">어디서 본 것 같다면&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>맞다. 스펙트로그램을 로그로 보는 것(dB), mel-spectrogram의 log 압축, μ-law 같은 것들이 전부 &amp;ldquo;큰 값은 세게, 작은 값은 약하게 누른다&amp;quot;는 같은 아이디어다. 논문도 이런 압축이 heavy-tailed한 음성 STFT 크기 분포를 보정하고, 음성 향상에서 지각적으로 더 의미 있다는 기존 연구를 근거로 든다. 차이라면 SGMSE는 로그가 아니라 power-law(&lt;span class="math math-inline">\(|c|^{0.5}\)&lt;/span>)를 써서 0 근처에서도 매끄럽고 역변환이 깔끔하다는 점.&lt;/p>
&lt;/div>
&lt;/aside>&lt;h2 id="참고-자료">참고 자료&lt;/h2>
&lt;ul>
&lt;li>J. Richter, S. Welker, J.-M. Lemercier, B. Lay, T. Gerkmann, &lt;a href="https://arxiv.org/abs/2208.05830" target="_blank" rel="noopener noreferrer">&lt;em>Speech Enhancement and Dereverberation with Diffusion-based Generative Models&lt;/em>&lt;/a>, IEEE/ACM TASLP 31, 2023. — 변환식, α=0.5·β=0.15, OU 드리프트 + Variance Exploding 확산으로 이루어진 SDE(OUVE)까지 이 논문.&lt;/li>
&lt;li>S. Welker, J. Richter, T. Gerkmann, &lt;a href="https://arxiv.org/abs/2203.17004" target="_blank" rel="noopener noreferrer">&lt;em>Speech Enhancement with Score-Based Generative Models in the Complex STFT Domain&lt;/em>&lt;/a>, Interspeech 2022. — 같은 그룹의 앞선 버전.&lt;/li>
&lt;li>코드: &lt;a href="https://github.com/sp-uhh/sgmse" target="_blank" rel="noopener noreferrer">sp-uhh/sgmse&lt;/a> — &lt;code>spec_transform&lt;/code> 쪽을 보면 위 식이 그대로 있다.&lt;/li>
&lt;/ul></content:encoded></item><item><title>MM-DiT — 두 모달리티를 동등하게 다루는 Diffusion Transformer</title><link>https://dirac042.github.io/posts/mm-dit/</link><pubDate>Mon, 06 Jul 2026 10:30:00 +0900</pubDate><guid>https://dirac042.github.io/posts/mm-dit/</guid><category>Deep Learning</category><category>Diffusion</category><category>Paper Notes</category><description>이전 노트에서 남긴 찝찝함 — 이미지/오디오가 주(主), 텍스트가 부(副)인 구조 — 을 정면으로 다루는 MM-DiT 정리. Stable Diffusion 3 논문(Esser et al., Scaling Rectified Flow Transformers for High-Resolution Image Synthesis, 2024)에서 제안됐다.</description><content:encoded>&lt;p>&lt;a href="https://dirac042.github.io/posts/dit/">이전 노트&lt;/a>에서 남긴 찝찝함 — 이미지/오디오가 주(主), 텍스트가 부(副)인 구조 — 을 정면으로 다루는 MM-DiT 정리. Stable Diffusion 3 논문(Esser et al., &lt;a href="https://arxiv.org/abs/2403.03206" target="_blank" rel="noopener noreferrer">&lt;em>Scaling Rectified Flow Transformers for High-Resolution Image Synthesis&lt;/em>&lt;/a>, 2024)에서 제안됐다.&lt;/p>
&lt;p>기존의 DiT 구조는 2가지의 모달리티에 계층이 존재했다.&lt;/p>
&lt;ol>
&lt;li>이미지, 오디오를 메인으로 두고,&lt;/li>
&lt;li>텍스트를 보조 힌트로 사용.&lt;/li>
&lt;/ol>
&lt;p>이렇게 되면 2개의 모달리티의 깊이가 달라서, Deeper Level의 Alignment가 잘 안 되는 문제가 생긴다.&lt;/p>
&lt;p>그러나 MM-DiT는 2개의 모달리티를 완벽하게 동등한 비중으로 다루게 된다.&lt;/p>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;ol>
&lt;li>Stream을 2개로 쪼개자!
&lt;ul>
&lt;li>Track A: Noise Token이 지나가는 길 (이미지/오디오)&lt;/li>
&lt;li>Track B: Text Token이 지나가는 길 (텍스트)
&lt;ul>
&lt;li>이때 텍스트는 힌트로 쓰이고 버려지지 않고, 이미지랑 똑같이 블록을 통과할 때마다 스스로 update된다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Joint Attention&lt;/strong>: 서로 다른 도로를 달리는 2개를 합치자!
&lt;ol>
&lt;li>이미지/텍스트는 성질이 달라서, 독립적인 Linear 신경망을 거쳐 QKV 제작&lt;/li>
&lt;li>이미지 QKV와 텍스트 QKV를 Sequential하게 이어붙이기 (매우 큰 공간)&lt;br>
→ 이 공간 안에서 토큰들이 서로 Attention (픽셀, 텍스트와의 관계 학습)&lt;br>
&amp;ldquo;사람들 4000명을 앉혀놓고, 전부 떠들게 만들기&amp;rdquo;&lt;/li>
&lt;li>정보를 가지게 된 토큰들을 다시 2개의 갈래로 나누기&lt;/li>
&lt;li>분리된 토큰들이 독립적인 MLP를 거쳐 최종적인 결과를 내리고, 다음 블럭으로 넘어가기&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ol>
&lt;figure class="post-figure">
&lt;img src="https://dirac042.github.io/images/fig-mmdit-block.png" alt="Image Description" loading="lazy" decoding="async">
&lt;/figure>&lt;blockquote>
&lt;p>한 블록의 흐름. 두 트랙은 가중치(adaLN, QKV, MLP)를 따로 갖고, attention 한 번만 같은 방에서 한다.&lt;/p>
&lt;/blockquote>&lt;aside class="callout callout-note">
&lt;p class="callout-title">SD3에서는 실제로 어떻게 조건을 만드나&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>텍스트 인코더를 세 개 쓴다: CLIP L/14, OpenCLIP bigG/14, T5-XXL. CLIP 두 개의 &lt;strong>pooled 출력&lt;/strong>을 이어 붙여 하나의 벡터로 만들고, 여기에 timestep 임베딩을 더해 adaLN의 조건 벡터(위 그림의 &amp;ldquo;t + pooled text&amp;rdquo;)로 쓴다. 반면 &lt;strong>토큰 단위 임베딩&lt;/strong>(CLIP의 penultimate hidden state + T5 토큰)은 Track B의 시퀀스가 되어 joint attention에 들어간다. 즉 &amp;ldquo;문장의 요약&amp;quot;은 modulation으로, &amp;ldquo;문장의 단어 하나하나&amp;quot;는 attention으로 들어가는 셈이다.&lt;/p>
&lt;p>그리고 이게 정말 나은지도 재봤다. 같은 조건에서 vanilla DiT &amp;lt; UViT &amp;lt; cross-attention DiT(CrossDiT) &amp;lt; &lt;strong>MM-DiT&lt;/strong> 순서였고, 논문은 &amp;ldquo;MM-DiT가 cross-attention과 vanilla 변형을 크게 앞선다&amp;quot;고 쓴다. 학습 목표는 DDPM 대신 rectified flow이고, 중간 timestep을 더 자주 뽑는 logit-normal 샘플링을 쓴다. 깊이 38(약 8B 파라미터)까지 키워도 validation loss가 포화 없이 계속 내려갔다.&lt;/p>
&lt;/div>
&lt;/aside>&lt;h2 id="problems">Problems&lt;/h2>
&lt;p>뭔가 데이터가 엄청나게 커지게 되면, Joint Attention이 엄청나게 느려질 것 같은 예감.&lt;/p>
&lt;ol>
&lt;li>Transformer Attention 연산은 &lt;span class="math math-inline">\(\mathcal{O}(N^2)\)&lt;/span>, 즉 데이터 길이의 제곱에 비례해 계산량이 늘어난다.
&lt;ul>
&lt;li>기존 방식은 Noise Token이 Text를 참고만 하니까, &lt;span class="math math-inline">\(\mathcal{O}(N^2)\)&lt;/span>.&lt;/li>
&lt;li>MM-DiT는 전부 다 몰아넣고 Attention을 실행하니까, &lt;span class="math math-inline">\(\mathcal{O}((N_{text}&amp;#43;N_{image})^2)\)&lt;/span>&lt;/li>
&lt;li>계산량이 매우매우 커진다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Attention 계산에서 OOM 에러&lt;/li>
&lt;li>Modality Imbalance하면 효율이 떨어진다.&lt;br>
ex. 텍스트 100개, 이미지 4만 개 → 이미지-이미지 간의 상호작용만 여러 개.&lt;/li>
&lt;/ol>
&lt;aside class="callout callout-note">
&lt;p class="callout-title">숫자로 감 잡기&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>1024×1024 이미지를 8배 VAE로 줄이면 128×128 latent, 패치 2로 자르면 &lt;span class="math math-inline">\(64^2=4096\)&lt;/span> 토큰. 텍스트는 CLIP 77 + T5 256 정도로 수백 개. 그러면 &lt;span class="math math-inline">\((4096&amp;#43;333)^2\approx1.96\times10^7\)&lt;/span> 대 &lt;span class="math math-inline">\(4096^2\approx1.68\times10^7\)&lt;/span> — 텍스트를 같은 방에 넣어서 늘어나는 비용은 약 17%다. 걱정과 달리 병목은 &amp;ldquo;텍스트를 끼워서&amp;quot;가 아니라 애초에 이미지-이미지 attention이고, 이건 self-attention을 쓰는 이상 어떤 DiT든 똑같이 진다. 오디오는 토큰이 시간축으로 길어지기 쉬워서(수천~수만 프레임) 이 항이 더 아프다.&lt;/p>
&lt;/div>
&lt;/aside>&lt;p>아직까지도 안 풀린 숙제로 남아 있다.&lt;/p>
&lt;ol>
&lt;li>Flash Attention 같은 최적화 기술을 영끌해서 적용하거나,&lt;/li>
&lt;li>3개의 블럭에서만 Joint Attention하고, 나머지는 분리해서 연산하는 등…&lt;/li>
&lt;/ol>
&lt;aside class="callout callout-note">
&lt;p class="callout-title">실제로 나온 절충안들&lt;/p>
&lt;div class="callout-body">
&lt;ul>
&lt;li>FLUX.1(Black Forest Labs, 2024)은 앞쪽에 두 트랙이 분리된 MM-DiT식 &lt;strong>double-stream&lt;/strong> 블록을 두고, 뒤쪽은 두 시퀀스를 아예 하나로 합쳐 처리하는 &lt;strong>single-stream&lt;/strong> 블록으로 바꿔 파라미터를 아낀다 — 위 2번 아이디어와 같은 방향이다.&lt;/li>
&lt;li>오디오 쪽에서는 MMAudio(Cheng et al., 2024)가 비디오·텍스트·오디오 세 스트림을 joint attention으로 묶고, 비디오-오디오 프레임을 시간축에 맞춰 정렬한 위치 임베딩(aligned RoPE)을 얹어 동기화 문제를 푼다.&lt;/li>
&lt;li>계산량 자체는 FlashAttention 계열이 메모리 병목을 크게 완화하지만 &lt;span class="math math-inline">\(\mathcal{O}(N^2)\)&lt;/span> 자체가 사라지진 않는다. 그래서 latent를 더 압축하거나(패치 크기, VAE 다운샘플 비율), 윈도우/희소 attention을 섞는 연구가 이어진다.&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/aside>&lt;h2 id="참고-자료">참고 자료&lt;/h2>
&lt;ul>
&lt;li>P. Esser et al., &lt;a href="https://arxiv.org/abs/2403.03206" target="_blank" rel="noopener noreferrer">&lt;em>Scaling Rectified Flow Transformers for High-Resolution Image Synthesis&lt;/em>&lt;/a>, 2024 — MM-DiT 원 논문(Stable Diffusion 3).&lt;/li>
&lt;li>W. Peebles, S. Xie, &lt;a href="https://arxiv.org/abs/2212.09748" target="_blank" rel="noopener noreferrer">&lt;em>Scalable Diffusion Models with Transformers&lt;/em>&lt;/a>, ICCV 2023 — 출발점인 DiT.&lt;/li>
&lt;li>H. K. Cheng et al., &lt;a href="https://arxiv.org/abs/2412.15322" target="_blank" rel="noopener noreferrer">&lt;em>MMAudio: Taming Multimodal Joint Training for High-Quality Video-to-Audio Synthesis&lt;/em>&lt;/a>, 2024 — 오디오에서의 multimodal joint attention.&lt;/li>
&lt;li>&lt;a href="https://github.com/black-forest-labs/flux" target="_blank" rel="noopener noreferrer">black-forest-labs/flux&lt;/a> — double/single-stream 블록 구현.&lt;/li>
&lt;/ul></content:encoded></item><item><title>DiT (Diffusion Transformer) 정리</title><link>https://dirac042.github.io/posts/dit/</link><pubDate>Mon, 06 Jul 2026 10:20:00 +0900</pubDate><guid>https://dirac042.github.io/posts/dit/</guid><category>Deep Learning</category><category>Diffusion</category><category>Paper Notes</category><description>Diffusion의 백본을 U-Net에서 Transformer로 바꾼 DiT(Peebles &amp; Xie, Scalable Diffusion Models with Transformers, ICCV 2023)를, 오디오 생성 관점에서 읽고 정리한 노트. 이전에 사용하던 U-Net 기반의 Diffusion은 이미지 생성 Task에서 많이 활용되어 왔다.</description><content:encoded>&lt;p>Diffusion의 백본을 U-Net에서 Transformer로 바꾼 DiT(Peebles &amp;amp; Xie, &lt;a href="https://arxiv.org/abs/2212.09748" target="_blank" rel="noopener noreferrer">&lt;em>Scalable Diffusion Models with Transformers&lt;/em>&lt;/a>, ICCV 2023)를, 오디오 생성 관점에서 읽고 정리한 노트.&lt;/p>
&lt;p>이전에 사용하던 U-Net 기반의 Diffusion은 이미지 생성 Task에서 많이 활용되어 왔다.&lt;/p>
&lt;ul>
&lt;li>하지만, U-Net의 구조적인 한계 때문에, 시간 간격이 긴 데이터에 약하다.&lt;/li>
&lt;li>즉, 앞의 데이터와 뒤의 데이터를 서로 연결할 수 있는 힘이 없다.&lt;/li>
&lt;/ul>
&lt;p>그래서 Transformer의 Attention 구조가 가진 Long-Term Dependency를 이용해 Transformer 기반의 Diffusion Method를 고안하게 되는데, 이것이 DiT라고 볼 수 있겠다.&lt;/p>
&lt;aside class="callout callout-note">
&lt;p class="callout-title">논문이 실제로 내세운 주장은 조금 다르다&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>위 직관(긴 의존성)은 오디오 쪽에서 DiT를 좋아하는 이유로 맞는 말이지만, 원 논문의 핵심 메시지는 &lt;strong>&amp;ldquo;U-Net의 inductive bias는 필수가 아니고, Transformer로 바꾸면 계산량(Gflops)을 늘릴수록 성능이 착실히 좋아진다&amp;rdquo;&lt;/strong> 는 스케일링 이야기다. 12개 모델 변형에서 Gflops와 FID-50K의 상관계수가 −0.93이었고, 가장 큰 DiT-XL/2(28층, hidden 1152, 16 heads)가 ImageNet 256×256 class-conditional에서 FID 2.27로 당시 SOTA를 찍었다. 입력은 픽셀이 아니라 Stable Diffusion VAE의 latent(256² 이미지 → 32×32×4)이고, ADM처럼 노이즈 ε과 공분산 Σ를 예측한다.&lt;/p>
&lt;/div>
&lt;/aside>&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;p>결국 Diffusion이 메인이라, Gaussian Noise에서 GT로 가는 방향을 예측하는 건 동일하다.&lt;/p>
&lt;p>즉, DiT의 Block은 현재 Timestep에서 입력된 Noisy Latent를 어떤 방향으로 Denoise할 것인지를 구하는 게 목표다.&lt;/p>
&lt;h3 id="patchify-latent를-토큰으로">Patchify: latent를 토큰으로&lt;/h3>
&lt;p>Transformer는 토큰의 시퀀스를 먹으니, 먼저 latent를 잘라야 한다. &lt;span class="math math-inline">\(I\times I\)&lt;/span> latent를 &lt;span class="math math-inline">\(p\times p\)&lt;/span> 패치로 자르면 토큰 수는 &lt;span class="math math-inline">\(T=(I/p)^2\)&lt;/span>. 논문은 &lt;span class="math math-inline">\(p\in\{2,4,8\}\)&lt;/span>을 실험했는데, &lt;span class="math math-inline">\(p\)&lt;/span>를 반으로 줄이면 토큰이 4배가 되고 Gflops도 최소 4배가 된다(파라미터 수는 거의 그대로). 그리고 그만큼 성능이 좋아진다 — 이것도 &amp;ldquo;계산량이 곧 성능&amp;quot;의 한 사례. 위치 정보는 ViT처럼 sine-cosine positional embedding으로 넣는다. 오디오라면 &lt;span class="math math-inline">\(I\times I\)&lt;/span> 대신 (시간 × 주파수/채널) latent를 같은 식으로 자르면 된다.&lt;/p>
&lt;h3 id="블록-안에서-일어나는-일">블록 안에서 일어나는 일&lt;/h3>
&lt;ol>
&lt;li>AdaLN (Adaptive Layer Normalization)
&lt;ul>
&lt;li>먼저 시간 &lt;span class="math math-inline">\(t\)&lt;/span>를 주입받아, 각각의 토큰들에게 &amp;lsquo;얼마나 깎아야 하는지&amp;rsquo;를 전달한다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Self-Attention
&lt;ul>
&lt;li>1에서 나온 정보들을 바탕으로, 각 토큰들은 자기 자신(Waveform) 안에서 패턴을 분석한다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Cross-Attention
&lt;ul>
&lt;li>이때 외부의 Condition(Video/Text)이 들어와 Denoising을 위한 힌트를 제공하고, 소리 생성의 방향성이 생긴다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>MLP
&lt;ul>
&lt;li>최종적으로 &amp;ldquo;이 소리는 이 방향으로 이동해야 한다!&amp;ldquo;를 구하게 된다.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;figure class="post-figure">
&lt;img src="https://dirac042.github.io/images/fig-dit-block.png" alt="Image Description" loading="lazy" decoding="async">
&lt;/figure>&lt;blockquote>
&lt;p>원 논문에서 가장 좋았던 adaLN-Zero 블록. 조건(t, c)은 attention이 아니라 LayerNorm의 scale/shift와 residual 앞의 gate로 들어간다.&lt;/p>
&lt;/blockquote>&lt;aside class="callout callout-note">
&lt;p class="callout-title">조건을 넣는 네 가지 방법 — 그리고 승자&lt;br>&lt;/p>
&lt;div class="callout-body">
&lt;p>위 1~4번은 &amp;ldquo;cross-attention을 쓰는 DiT&amp;quot;의 그림이다(오디오/텍스트 조건 모델들이 실제로 이렇게 쓴다). 그런데 원 논문은 조건(timestep &lt;span class="math math-inline">\(t\)&lt;/span>, class label &lt;span class="math math-inline">\(c\)&lt;/span>)을 주입하는 방법을 네 가지 비교했다.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>방식&lt;/th>
&lt;th>어떻게&lt;/th>
&lt;th>비용&lt;/th>
&lt;th>결과&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>In-context&lt;/td>
&lt;td>&lt;span class="math math-inline">\(t\)&lt;/span>, &lt;span class="math math-inline">\(c\)&lt;/span> 임베딩을 토큰 두 개로 시퀀스 앞에 붙임&lt;/td>
&lt;td>거의 0&lt;/td>
&lt;td>가장 나쁨&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Cross-attention&lt;/td>
&lt;td>조건 시퀀스에 대해 별도 cross-attn 층&lt;/td>
&lt;td>약 +15% Gflops&lt;/td>
&lt;td>중간&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>adaLN&lt;/td>
&lt;td>조건 벡터에서 LayerNorm의 scale γ, shift β를 회귀&lt;/td>
&lt;td>가장 적음&lt;/td>
&lt;td>좋음&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>adaLN-Zero&lt;/strong>&lt;/td>
&lt;td>adaLN + residual 직전의 dimension-wise gate α를 &lt;strong>0으로 초기화&lt;/strong>&lt;/td>
&lt;td>가장 적음&lt;/td>
&lt;td>&lt;strong>최고&lt;/strong> (400K step에서 FID가 in-context의 거의 절반)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>adaLN-Zero의 아이디어는 학습 초기에 각 블록이 항등함수(identity)에서 출발하게 만드는 것. 그래서 위 그림의 α가 &amp;ldquo;0으로 초기화&amp;quot;다. 정리하면 — 조건이 &amp;ldquo;짧은 벡터&amp;rdquo;(timestep, class, pooled text)라면 adaLN 계열이, 조건이 &amp;ldquo;긴 시퀀스&amp;rdquo;(문장 토큰, 비디오 프레임)라면 cross-attention이 자연스럽다. Stable Audio Open 같은 오디오 DiT가 텍스트 토큰은 cross-attention으로, timestep/타이밍 조건은 adaLN으로 넣는 이유가 여기 있다.&lt;/p>
&lt;/div>
&lt;/aside>&lt;h2 id="commentary">Commentary&lt;/h2>
&lt;p>찝찝한 부분이 있다.&lt;/p>
&lt;p>현재 DiT에서는 Self-Attention에서 Waveform의 패턴을 분석한 다음,&lt;br>
부가적으로 Condition이 들어와 Denoising을 시행한다.&lt;/p>
&lt;p>그 말인즉슨, Waveform이 주(主), Video/Text가 부(副)가 되는 형태라고 볼 수 있겠다.&lt;/p>
&lt;p>이런 식으로 이미지/오디오가 메인, 텍스트가 보조가 되면 정보 불균형이 생기지 않을까?&lt;/p>
&lt;p>이걸 Hierarchical하지 않고, Equal하게 다룰 수는 없을까?&lt;/p>
&lt;p>→ 다음 노트: &lt;a href="https://dirac042.github.io/posts/mm-dit/">MM-DiT&lt;/a>&lt;/p>
&lt;h2 id="참고-자료">참고 자료&lt;/h2>
&lt;ul>
&lt;li>W. Peebles, S. Xie, &lt;a href="https://arxiv.org/abs/2212.09748" target="_blank" rel="noopener noreferrer">&lt;em>Scalable Diffusion Models with Transformers&lt;/em>&lt;/a>, ICCV 2023. 코드: &lt;a href="https://github.com/facebookresearch/DiT" target="_blank" rel="noopener noreferrer">facebookresearch/DiT&lt;/a>.&lt;/li>
&lt;li>P. Esser et al., &lt;a href="https://arxiv.org/abs/2403.03206" target="_blank" rel="noopener noreferrer">&lt;em>Scaling Rectified Flow Transformers for High-Resolution Image Synthesis&lt;/em>&lt;/a>, 2024 (Stable Diffusion 3) — DiT를 두 모달리티 동등 구조로 확장한 MM-DiT.&lt;/li>
&lt;li>Z. Evans et al., &lt;a href="https://arxiv.org/abs/2407.14358" target="_blank" rel="noopener noreferrer">&lt;em>Stable Audio Open&lt;/em>&lt;/a>, 2024 — 오디오 latent 위에서 돌아가는 DiT의 실제 예 (T5 텍스트는 cross-attention, 타이밍 조건은 adaLN).&lt;/li>
&lt;/ul></content:encoded></item></channel></rss>