Study · Model anatomy
Inside SDAR: a block-diffusion LM, tensor by tensorSDAR: block-diffusion LM 해부
SDAR-style models keep the ordinary decoder transformer — same weights, same shapes — and change only how it reads and writes text: autoregressive across blocks, parallel diffusion-denoising inside each block (블록 단위로). Walk the stack, open a layer, then step through decoding and watch the KV cache grow. SDAR 계열 모델은 평범한 decoder transformer를 그대로 둔 채 — weight도 shape도 같다 — 텍스트를 읽고 쓰는 방식만 바꾼다: block 사이는 autoregressive, 각 block 내부는 병렬 diffusion-denoising이다(블록 단위로). 스택을 따라 내려가고, layer 하나를 열어 본 뒤, 디코딩을 한 단계씩 밟으며 KV cache가 자라는 모습을 지켜보자.
§1The itch — one pass, one token문제의식 — pass 하나에 token 하나
An autoregressive language model writes like a careful typist: one token, then the next, each requiring a full trip through the network. For the 1.7 B-parameter model on this page, one such trip drags roughly 3.4 GB of weights out of GPU memory — all of that traffic to decide a single word. At batch size 1 the arithmetic units are mostly idle; the wait is the memory traffic, so the number of passes is, to first order, the latency. A 500-token answer costs 500 trips through the same 3.4 GB. autoregressive 언어 모델은 신중한 타이피스트처럼 쓴다: token 하나, 그다음 하나 — 매번 네트워크 전체를 통과해야 한다. 이 페이지의 1.7 B-parameter 모델이라면 그 한 번의 통과가 대략 3.4 GB의 weight를 GPU 메모리에서 끌어낸다 — 그 트래픽 전부가 단어 하나를 정하기 위한 것이다. batch size 1에서 연산 유닛은 대부분 놀고 있고, 기다림의 정체는 메모리 트래픽이므로 pass 횟수가 사실상 latency다. 500-token짜리 답은 같은 3.4 GB를 500번 도는 값이다.
Diffusion language models attack the pass count directly: predict many positions in one pass, and the trips divide. But the pure form gives up the other thing that makes AR serving fast — never redoing work on text that is already written. SDAR-style block diffusion is the study of how to keep both, and the small figure below is its whole promise in one line: the same 8 tokens, in 5 passes instead of 8. diffusion 언어 모델은 pass 횟수를 정면으로 공격한다: 한 pass에 여러 위치를 예측하면 왕복 횟수가 나눠진다. 하지만 순수한 형태는 AR serving을 빠르게 만드는 나머지 한 축 — 이미 써 놓은 텍스트에 대한 작업을 절대 반복하지 않는 것 — 을 포기한다. SDAR 계열 block diffusion은 이 둘을 어떻게 다 지키는가에 대한 공부이고, 아래 작은 그림이 그 약속의 전부다: 같은 8개 token을 8번이 아니라 5번의 pass로.
How can a model even predict several positions at once — and what does that break? 애초에 모델이 여러 위치를 동시에 예측하는 게 어떻게 가능하고, 그러면 무엇이 깨질까?
§2Foundations — the cache and the mask기초 다지기 — cache와 mask
Two background ideas make everything on this page legible. First, the KV cache. Inside a transformer, every position computes attention over the positions it is allowed to see, and for each visible position the layer needs two vectors — a key and a value. In an AR model the visibility rule is causal: a token sees only its past. That rule has a golden consequence: the past never changes, so the K and V of already-written tokens can be computed once, stored, and reused for every later token. Decoding one new token then costs one pass over the weights plus cheap reads from this cache — and the cached values are exact: recomputing them would reproduce them bit for bit. 이 페이지 전체를 읽히게 만드는 배경 아이디어는 두 개다. 첫째, KV cache. transformer 안에서 각 위치는 자신이 볼 수 있는 위치들에 대해 attention을 계산하고, 보이는 위치마다 layer는 vector 두 개 — key와 value — 를 필요로 한다. AR 모델의 가시성 규칙은 causal이다: token은 자기 과거만 본다. 이 규칙의 황금 같은 귀결: 과거는 절대 변하지 않으므로, 이미 써 놓은 token들의 K와 V는 한 번 계산해 저장해 두고 이후 모든 token이 재사용할 수 있다. 새 token 하나를 디코딩하는 비용은 weight 한 번 통과 + 이 cache에서의 값싼 읽기가 전부다 — 그리고 cache된 값은 정확(exact)하다: 다시 계산해도 bit 단위로 같은 값이 나온다.
Second, masked-diffusion generation. Instead of
appending one token at a time, the output starts as a row of [MASK]
placeholders. Each forward pass, the model reads the whole sequence —
bidirectionally, future slots included — and proposes a token for every masked
position at once; the most confident proposals are kept, the rest stay masked for
another pass. That is exactly the many-tokens-per-pass parallelism §1 asked for. 둘째, masked-diffusion 생성. token을 하나씩
덧붙이는 대신, 출력이 [MASK] placeholder 행렬로 시작한다. forward pass마다
모델은 시퀀스 전체를 — 미래 슬롯까지 포함해 bidirectional하게 — 읽고 mask된
모든 위치에 대해 동시에 token을 제안한다; confidence가 높은 제안은 확정되고, 나머지는
다음 pass를 위해 mask로 남는다. §1이 요구한 pass당 여러 token 병렬성이 정확히
이것이다.
Now the collision. Bidirectionality poisons the cache: if position 7 may attend to position 12, then the K/V computed at 7 depend on whatever currently occupies 12 — and that keeps changing until 12 is final. Nothing is safely “the past”; any stored vector can go stale, so full-attention diffusion LMs must either recompute constantly or manage an approximate cache. Caching wants immutability; parallelism wants bidirectionality — one attention mask cannot grant both everywhere. 이제 충돌이다. bidirectionality는 cache에 독이 된다: 위치 7이 위치 12에 attend할 수 있다면, 7에서 계산된 K/V는 지금 12에 놓인 것이 무엇이냐에 의존하는데 — 그것은 12가 확정될 때까지 계속 바뀐다. 그 무엇도 안전한 “과거”가 아니고, 저장해 둔 vector는 언제든 stale해질 수 있다. 그래서 full-attention diffusion LM은 끊임없이 재계산하거나 근사 cache를 관리해야 한다. caching은 불변성을 원하고, 병렬성은 bidirectionality를 원한다 — attention mask 하나가 모든 곳에서 둘 다 줄 수는 없다.
The escape is to stop demanding one answer everywhere: keep bidirectionality inside a small window and causality across windows. That single move is block diffusion, and it forces everything else on this page — the mask in §4, the decoding loop in §5, even the fact that §3 will look boringly familiar. 탈출구는 모든 곳에서 하나의 답을 요구하지 않는 것이다: 작은 창 안쪽에서는 bidirectionality를, 창 사이에서는 causality를 유지한다. 이 한 수가 block diffusion이고, 이 페이지의 나머지 전부 — §4의 mask, §5의 디코딩 루프, 심지어 §3이 지루할 만큼 낯익어 보일 것이라는 사실까지 — 를 강제한다.
If the fix is just a mask, what happens to the model itself? 고치는 게 mask뿐이라면, 모델 자체는 무엇이 달라질까?
§3The model stack모델 스택
We now know the shape of the compromise — bidirectional inside, causal across. The first surprise is what it costs the network: nothing. Here is the entire model, weight by weight. 타협의 모양은 이제 안다 — 안쪽은 bidirectional, 사이는 causal. 첫 번째 놀라움은 이것이 네트워크에 요구하는 대가다: 없다. 아래가 모델 전체, weight 하나하나다.
Hover any box for exact parameter counts and bytes. Click a transformer block to open its internals. 박스에 마우스를 올리면 정확한 parameter 수와 byte 수가 보인다. transformer block을 클릭하면 내부가 열린다.
There is no diffusion-specific machinery in the weights. The stack is a plain dense decoder: a 151,936 × 2,048 tied embedding (311 M parameters), 28 identical transformer blocks of about 50.3 M parameters each, a final RMSNorm, and the transposed embedding as the LM head — roughly 1.72 B parameters, 3.4 GB in BF16. This is why SDAR-style models can be adapted from a pretrained AR checkpoint rather than trained from scratch: the published recipe starts from Qwen3 weights and continues training with a block-diffusion objective. Everything that makes the model “diffusion” lives in two places outside the weights: the attention mask and the decoding loop. weight 안에는 diffusion 전용 장치가 하나도 없다. 스택은 평범한 dense decoder다: 151,936 × 2,048 tied embedding(311 M parameter), 각각 약 50.3 M parameter인 동일한 transformer block 28개, 마지막 RMSNorm, 그리고 embedding의 transpose를 LM head로 쓴다 — 대략 1.72 B parameter, BF16으로 3.4 GB. SDAR 계열 모델을 처음부터 학습하는 대신 사전학습된 AR checkpoint에서 적응(adapt)시킬 수 있는 이유가 여기에 있다: 공개된 레시피는 Qwen3 weight에서 출발해 block-diffusion objective로 학습을 이어 간다. 이 모델을 “diffusion”으로 만드는 모든 것은 weight 바깥의 두 곳에 산다: attention mask와 디코딩 루프.
So where exactly does that mask sit inside a layer — and what does it change? 그렇다면 그 mask는 layer 안 정확히 어디에 앉아 있고, 무엇을 바꿀까?
§4Inside one transformer blockTransformer block 하나의 내부
The stack told us where the diffusion is not. This section opens one of the 28 blocks to find where it is: a single mask added to the attention scores — the compromise from §2, drawn cell by cell. 스택은 diffusion이 없는 곳을 알려 줬다. 이 섹션은 28개 block 중 하나를 열어 diffusion이 있는 곳을 찾는다: attention score에 더해지는 mask 하나 — §2의 타협을 셀 단위로 그린 것이다.
Left: the dataflow with every weight matrix and its shape. Right: the block-causal attention mask — hover a row to see exactly which K/V positions that query may read. 왼쪽: 모든 weight matrix와 그 shape을 담은 dataflow. 오른쪽: block-causal attention mask — 행에 마우스를 올리면 그 query가 읽을 수 있는 K/V 위치가 정확히 표시된다.
Hover a row: each row is one query position; filled cells are the K/V positions it may attend to. Coral cells right of the dashed diagonal are exactly what block diffusion adds over an AR mask. 행에 마우스를 올려 보자: 각 행은 query 위치 하나이고, 채워진 셀은 그 query가 attend할 수 있는 K/V 위치다. 점선 대각선 오른쪽의 coral 셀이 바로 block diffusion이 AR mask 위에 더하는 가시성이다.
Inside a block: pre-RMSNorm, then Q/K/V projections. The config is GQA-shaped — 16 query heads of dimension 128 (WQ: 2,048 → 2,048) but only 8 KV heads (WK, WV: 2,048 → 1,024), so each K/V head serves two query heads and the cache is half the size it would be with MHA. After per-head QK-norm and RoPE comes the one genuinely different ingredient: the block-causal mask. Partition positions into blocks of 4. A query may attend to every position in earlier blocks (ordinary causal attention — those K/V come straight from the cache) and to every position of its own block, including future ones. In the matrix panel, the coral cells to the right of the dashed diagonal are precisely the visibility that a causal AR mask forbids — and they are what lets several tokens be predicted jointly in one pass. The MLP is a standard SwiGLU (2,048 → 6,144 → 2,048, 37.75 M parameters per layer — three times the attention weights). block 내부: pre-RMSNorm 다음 Q/K/V projection. config는 GQA 형태다 — dimension 128짜리 query head 16개(WQ: 2,048 → 2,048)에 KV head는 8개뿐이라 (WK, WV: 2,048 → 1,024), K/V head 하나가 query head 두 개를 감당하고 cache는 MHA였을 때의 절반 크기다. per-head QK-norm과 RoPE 다음에 진짜로 다른 단 하나의 재료가 온다: block-causal mask. 위치들을 4개씩 block으로 나눈다. query는 이전 block의 모든 위치(일반적인 causal attention — 그 K/V는 cache에서 바로 온다)와, 미래 위치를 포함한 자기 block의 모든 위치에 attend할 수 있다. matrix 패널에서 점선 대각선 오른쪽의 coral 셀이 정확히 causal AR mask가 금지하는 가시성이며 — 여러 token을 한 pass에 함께 예측할 수 있게 해 주는 것이 바로 이들이다. MLP는 표준 SwiGLU다 (2,048 → 6,144 → 2,048, layer당 37.75 M parameter — attention weight의 3배).
A mask only says who may look at whom — how does a block of four [MASK]s actually become text? mask는 누가 누구를 봐도 되는지만 말한다 — [MASK] 4개짜리 block은 실제로 어떻게 텍스트가 될까?
§5Decoding timeline디코딩 타임라인
This is the hardest section of the page — the full decoding loop, where the mask, the confidence rule and the cache all interact at once. Take it slowly: step with “Next” rather than “Play”, and read each caption before moving on. 여기가 이 페이지에서 가장 어려운 섹션이다 — mask, confidence 규칙, cache가 한꺼번에 맞물리는 디코딩 루프 전체. 천천히 가자: “Play” 대신 “Next”로 한 단계씩 밟고, 캡션을 읽고 나서 넘어가는 것을 권한다.
Step through block-by-block generation: masked slots are denoised in parallel, commits follow confidence, and each finalized block appends exact K/V entries to the cache. block 단위 생성을 한 단계씩 따라가 보자: mask된 슬롯이 병렬로 denoise되고, commit은 confidence를 따르며, 확정된 각 block은 정확한(exact) K/V 엔트리를 cache에 추가한다.
Prefill — the 5-token prompt runs through all 28 layers once. Every layer writes K and V for the 5 positions: 5 × 112 KB = 560 KB of cache. Identical to an AR model so far. Prefill — 5-token prompt가 28개 layer를 한 번 통과한다. 모든 layer가 5개 위치의 K와 V를 기록한다: 5 × 112 KB = 560 KB의 cache. 여기까지는 AR 모델과 동일하다.
Generation appends a block of 4 [MASK] tokens and denoises it over a few
forward passes. Each pass produces a full 151,936-way distribution at every masked
position simultaneously; positions whose confidence clears a threshold τ are committed
(at least the argmax is, so progress is guaranteed), and committed tokens condition the
next pass. Commit order follows confidence, not left-to-right position. In the timeline
above, 8 tokens land in 5 denoising passes instead of 8 AR steps. When a block is
finished it is frozen; because cross-block attention is causal, its K and V are
exact — bit-for-bit what an AR pass would have produced — so they are appended
to the cache once and never touched again. The cache simply grows in block-sized
strides: 112 KB per token in this config. 생성은 [MASK] token 4개짜리 block을 덧붙이고 몇 번의
forward pass에 걸쳐 denoise한다. 각 pass는 mask된 모든 위치에서 동시에 151,936-way
분포를 만든다; confidence가 threshold τ를 넘는 위치는 commit되고(최소한 argmax 하나는
commit되므로 진행이 보장된다), commit된 token은 다음 pass의 조건이 된다. commit 순서는
왼쪽에서 오른쪽 위치 순이 아니라 confidence를 따른다. 위 타임라인에서는 AR step 8번 대신
denoising pass 5번에 token 8개가 확정된다. block이 끝나면 동결된다; block 사이 attention이
causal이므로 그 K와 V는 정확(exact)하다 — AR pass가 만들었을 값과 bit 단위로
같다 — 그래서 cache에 한 번 추가되면 다시는 손대지 않는다. cache는 그저 block 크기 보폭으로
자란다: 이 config에서 token당 112 KB.
What does this buy at serving time — and what is still unsolved? 이것이 serving에서 무엇을 사 주고, 무엇은 아직 미해결일까?
§6Where this goes이 다음
Zoom back out. What we just walked is one released design point — block length 4, one confidence rule, one adapted backbone. Why it matters for serving, and where the field is pushing next. 다시 넓게 보자. 방금 밟은 것은 공개된 설계점 하나다 — block length 4, confidence 규칙 하나, adapt된 backbone 하나. 이것이 serving에 왜 중요한지, 그리고 이 분야가 지금 어디를 밀고 있는지.
Why this matters for efficiency이것이 효율에 중요한 이유
Two separate levers hide in this design. Within-block parallelism attacks the weight-read floor. Batch-1 decoding is memory-bound: every forward pass streams all ≈3.4 GB of weights through the GPU regardless of how many tokens it commits, so a pass that commits 2–3 tokens cuts the weight traffic per token by 2–3×. The tokens-per-pass ratio, controlled by the confidence threshold and block size, is nearly free throughput. Block-causality makes KV reuse exact. Full-attention diffusion LMs let every position keep revising, so any cached K/V can go stale and cache reuse becomes an approximation to manage. Here, finalized blocks are immutable by construction — the cache is append-only and exact, the same contract an AR engine relies on. The trade lives between the two levers: larger blocks buy more parallelism but weaken left-to-right conditioning inside the block; the released SDAR checkpoints settle at a short block length of 4. 이 설계에는 서로 다른 지렛대 두 개가 숨어 있다. block 내 병렬성은 weight-read 바닥을 공략한다. batch-1 디코딩은 memory-bound다: forward pass는 commit하는 token 수와 무관하게 매번 ≈3.4 GB weight 전체를 GPU로 흘려보내므로, 한 pass가 token 2–3개를 commit하면 token당 weight 트래픽이 2–3배 줄어든다. confidence threshold와 block 크기로 조절되는 tokens-per-pass 비율은 거의 공짜 throughput이다. block-causality는 KV 재사용을 정확(exact)하게 만든다. full-attention diffusion LM은 모든 위치가 계속 수정될 수 있어 cache된 K/V가 언제든 stale해질 수 있고, cache 재사용은 관리해야 할 근사가 된다. 여기서는 확정된 block이 구조적으로 불변이다 — cache는 append-only이고 정확하며, AR 엔진이 의존하는 것과 같은 계약이다. 트레이드오프는 두 지렛대 사이에 있다: block이 클수록 병렬성은 커지지만 block 내부의 left-to-right 조건화가 약해진다; 공개된 SDAR checkpoint들은 짧은 block length 4에 정착했다.
The frontier around this design is active on several sides. One line of work keeps the full-attention diffusion form and manages the approximate cache it implies — LLaDA established the model class, and Fast-dLLM shows how far training-free caching and parallel decoding can push it. A second line scales the block-diffusion recipe itself to much larger models — see Nemotron-Diffusion. A third asks how to steer parallel decoding: for instance, enforcing output constraints when tokens no longer arrive left-to-right (constrained decoding for dLLMs). 이 설계 주변의 최전선은 여러 방향에서 움직이고 있다. 한 갈래는 full-attention diffusion 형태를 유지한 채 그것이 강제하는 근사 cache를 관리한다 — LLaDA가 이 모델 클래스를 세웠고, Fast-dLLM은 training-free caching과 병렬 디코딩이 어디까지 갈 수 있는지 보여 준다. 두 번째 갈래는 block-diffusion 레시피 자체를 훨씬 큰 모델로 스케일한다 — Nemotron-Diffusion을 보라. 세 번째는 병렬 디코딩을 어떻게 조종할지 묻는다: 예컨대 token이 더 이상 왼쪽에서 오른쪽으로 도착하지 않을 때 출력 제약을 지키는 문제 (dLLM constrained decoding)다.
And plenty is unsolved: how the block-size / quality trade-off behaves at scale, how to schedule the threshold τ instead of fixing it, how block-causal attention holds up at long context, and how block-diffusion decoding composes with the batching and scheduling machinery of real serving stacks. The mechanics on this page are the fixed vocabulary those questions are asked in. 미해결 문제도 잔뜩 남아 있다: block 크기 / 품질 트레이드오프가 스케일에서 어떻게 움직이는지, threshold τ를 고정하는 대신 어떻게 스케줄링할지, block-causal attention이 long context에서 어떻게 버티는지, block-diffusion 디코딩이 실제 serving 스택의 batching·scheduling 장치와 어떻게 결합하는지. 이 페이지의 메커니즘은 그 질문들을 서술하는 고정 어휘다.
Going deeper더 깊이 읽기
- SDAR — model family, checkpoints & tech report (GitHub) — 모델 패밀리, checkpoint & tech report (GitHub)
- Block Diffusion (BD3-LM) — interpolating between AR and diffusion LMs — AR와 diffusion LM 사이를 보간하는 모델
- LLaDA — large language diffusion models (full-attention dLLM) — 대규모 language diffusion 모델 (full-attention dLLM)
- Fast-dLLM — KV caching & parallel decoding for diffusion LLMs — diffusion LLM을 위한 KV caching & parallel decoding
- Qwen3 technical report — the backbone family — backbone 모델 패밀리
Shapes on this page assume the public SDAR-1.7B configuration (Qwen3-1.7B backbone: d = 2,048, 28 layers, 16 Q / 8 KV heads, head_dim 128, FFN 6,144, vocab 151,936, block length 4). The larger released variants (4B, 8B, and the 30B-A3B MoE) change widths and depths, not the mechanics shown here. Confidence numbers in the timeline are illustrative. 이 페이지의 shape들은 공개된 SDAR-1.7B configuration을 가정한다 (Qwen3-1.7B backbone: d = 2,048, 28 layers, 16 Q / 8 KV heads, head_dim 128, FFN 6,144, vocab 151,936, block length 4). 더 큰 공개 변형들(4B, 8B, 그리고 30B-A3B MoE)은 폭과 깊이만 다를 뿐, 여기서 보인 메커니즘은 같다. 타임라인의 confidence 숫자는 예시용이다.