본문으로 건너뛰기
CometML Blog조회 1

Diffusion 언어 모델의 속도와 품질 사이 균형

Diffusion LM은 병렬 정제로 응답을 앞당기지만 hard task 품질을 희생합니다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

Diffusion language model은 토큰을 왼쪽에서 오른쪽으로 하나씩 확정하는 대신, [MASK]로 손상된 전체 시퀀스를 여러 단계에 걸쳐 병렬 denoising하며 생성합니다. 이 구조는 양방향 문맥과 반복 수정, 짧은 응답의 낮은 latency를 제공하지만 한 단계에서 여러 토큰을 독립적으로 예측하는 가정 때문에 토큰 의존성이 높은 어려운 작업에서 품질이 떨어집니다. 작은 모델 실험에서는 2단계 생성이 무너지고 24단계에서 학습 문장에 가까운 결과를 냈으며, Mercury 2 평가에서는 Claude Haiku 4.5보다 평균 응답이 3.0초 대 6.0초로 빨랐지만 pass rate는 84% 대 99.7%였습니다. Mercury 2는 easy·medium code task와 latency 중심 환경에 적합하고, hard task에서는 high reasoning_effort를 사용하거나 더 높은 정확도를 위해 Autoregressive model을 선택해야 합니다.

섹션별 상세

01
Autoregressive Transformer가 사실상 Language model의 표준처럼 받아들여진 상황에서 State-space model, looped Transformer, Diffusion model이 실제 제품 환경으로 이동하고 있습니다. Diffusion language model은 토큰을 왼쪽에서 오른쪽으로 하나씩 확정하지 않고 전체 시퀀스를 여러 번 정제하므로 앞부분을 뒤 토큰의 문맥에 맞춰 수정할 수 있습니다. Google의 Gemini Diffusion은 coding benchmark에서 Autoregressive model과 경쟁했고, DiffusionGemma는 기반이 된 Gemma 4보다 최대 4배 빠르지만 품질 비용이 따릅니다.
가려진 텍스트 토큰들이 여러 위치에서 동시에 채워지고 반복 단계마다 문장이 수정되는 Diffusion 생성 애니메이션입니다.
Diagram이미지는 왼쪽에서 오른쪽으로 한 토큰씩 확정하는 Autoregressive 방식과 달리, Diffusion 방식이 전체 시퀀스의 여러 위치를 병렬로 정제하는 과정을 시각화합니다. 앞서 채운 토큰도 이후 문맥에 따라 바뀔 수 있다는 점이 텍스트 생성의 핵심 차이입니다.
Autoregressive 생성은 한 토큰씩 왼쪽에서 오른쪽으로 진행되고 Diffusion 생성은 여러 위치를 병렬로 정제하는 차이를 비교한 애니메이션입니다.
Diagram상단의 Autoregressive 흐름은 이전 출력이 다음 입력이 되는 순차 구조를, 하단의 Diffusion 흐름은 여러 마스킹 위치가 동시에 복원되는 구조를 나타냅니다. 이 차이가 Diffusion의 latency 이점과 조건부 독립 가정에 따른 품질 저하를 함께 만듭니다.
02
텍스트 Diffusion은 이미지의 Gaussian noise를 [MASK] 토큰으로 바꾸어 이산적인 손상 과정을 구성합니다. 모델은 마스킹된 위치를 양방향 문맥에서 동시에 예측하고, 매 단계 확신도가 높은 토큰을 공개해 다음 단계의 입력으로 재사용합니다. 이 구조는 병렬 처리와 수정 가능성을 제공하지만 자연어 토큰의 의존성을 조건부 독립으로 근사하면서 어려운 작업의 정확도가 낮아질 수 있습니다.
이미지 Diffusion의 forward 과정에서 Gaussian noise가 추가되고 reverse 과정에서 noise가 제거되는 흐름을 나타낸 도식입니다.
Diagram이미지는 원본 이미지가 단계적으로 순수한 noise로 바뀐 뒤 reverse 과정에서 denoising되는 구조를 설명합니다. 기사에서는 이 연속적인 이미지 손상을 텍스트의 [MASK] 치환으로 재정의해 masked diffusion을 구성합니다.
문장의 토큰을 0%에서 100%까지 점진적으로 마스킹하는 과정과 BERT의 고정 15% 마스킹 지점을 비교한 시각 자료입니다.
Diagram문장 전체가 보이는 상태에서 토큰이 가려져 완전히 빈 시퀀스가 되는 과정은 t가 corruption level을 조절한다는 내용을 나타냅니다. BERT의 단일 마스킹 비율과 달리 masked diffusion은 여러 마스킹 수준에서 복원하도록 학습합니다.
ParallelBench의 Copy, Reverse, Replace Index, Replace Random, Shuffle, Paraphrasing, W2S, Sudoku, Latin Square task에서 tokens per step와 accuracy의 관계를 나타낸 10개 그래프입니다.
ChartCopy처럼 토큰 의존성이 낮은 task에서는 한 단계에 많은 토큰을 처리해도 accuracy가 유지되지만, Shuffle과 Words-to-Sentence hard에서는 병렬 처리량이 증가할수록 accuracy가 급격히 낮아집니다. Diffusion decoding의 속도와 품질이 task의 토큰 의존성에 따라 달라진다는 기사 내용을 뒷받침합니다.
03
Masked diffusion의 학습 목표는 임의의 마스킹 비율 t를 선택하고 손상된 시퀀스에서 [MASK] 위치의 원래 토큰만 cross-entropy로 평가하는 방식입니다. BERT가 약 15%의 고정 마스킹 비율을 사용한다면, Diffusion model은 0%에서 100%까지의 마스킹 수준을 학습해 완전히 빈 시퀀스에서 출발하는 생성 과정을 익힙니다. 손실 가중치 w(t)를 적용하면 이 목표는 시퀀스 likelihood와 연결되며, 구현에서는 학습 안정성을 위해 단순화될 수 있습니다.
python
class Denoiser(nn.Module):
    def __init__(self, vocab=VOCAB, d=64, heads=4, layers=2, block=BLOCK):
        super().__init__()
        self.tok = nn.Embedding(vocab, d)
        self.pos = nn.Embedding(block, d)
        self.time = nn.Sequential(nn.Linear(1, d), nn.GELU(), nn.Linear(d, d))
        enc = nn.TransformerEncoderLayer(d, heads, dim_feedforward=4*d, batch_first=True,
                                         activation="gelu")
        self.blocks = nn.TransformerEncoder(enc, layers)
        self.ln = nn.LayerNorm(d)
        self.head = nn.Linear(d, vocab)

    def forward(self, x, t):
        pos = torch.arange(x.size(1))
        h = self.tok(x) + self.pos(pos)[None]
        h = h + self.time(t[:, None])[:, None, :]
        h = self.blocks(h)
        return self.head(self.ln(h))

인과 마스크를 제거한 Transformer encoder가 양방향 문맥에서 각 위치의 원래 토큰 확률을 계산합니다.

python
def train(steps=2500, lr=3e-4):
    model = Denoiser()
    opt = torch.optim.AdamW(model.parameters(), lr=lr)
    for step in range(steps):
        x = get_batch()
        xt, mask, t = add_noise(x)
        logits = model(xt, t)
        loss = F.cross_entropy(logits[mask], x[mask])
        opt.zero_grad(); loss.backward(); opt.step()
    return model

마스킹된 배치만 모델에 통과시킨 뒤 손상된 위치의 예측에 대해서만 cross-entropy 손실을 계산합니다.

python
@torch.no_grad()
def sample(model, n_steps, length=BLOCK):
    x = torch.full((1, length), MASK, dtype=torch.long)
    reveal_per_step = math.ceil(length / n_steps)
    for s in range(n_steps):
        t = torch.tensor([(x[0] == MASK).float().mean()])
        probs = F.softmax(model(x, t), -1)[0]
        pred = torch.multinomial(probs, 1).squeeze(-1)
        conf = probs.gather(-1, pred[:, None]).squeeze(-1)
        masked = (x[0] == MASK)
        if masked.sum() == 0:
            break
        cand = torch.where(masked, conf, torch.full_like(conf, -1.0))
        k = min(reveal_per_step, int(masked.sum().item()))
        idx = torch.topk(cand, k).indices
        x[0, idx] = pred[idx]
    left = (x[0] == MASK)
    if left.any():
        x[0, left] = model(x, torch.tensor([0.0]))[0, left].argmax(-1)
    return "".join(itos[i.item()] for i in x[0])

완전히 마스킹된 시퀀스에서 시작해 매 단계 확신도가 높은 예측을 공개하고, 남은 위치를 다음 단계의 문맥으로 넘깁니다.

04
작은 문자 단위 Diffusion LM은 5개 문장을 반복한 데이터와 24자 블록으로 학습되며, 인과 마스크가 없는 Transformer encoder를 denoiser로 사용합니다. 2단계 샘플링은 거의 모든 위치를 한꺼번에 확정해 'he on the ohta troc'처럼 구조가 무너졌지만, 8단계에서는 단어 일부가 유지되고 24단계에서는 학습 문장에 가까운 'the dog ran in the par...'가 나왔습니다. 단계 수와 단계별 공개 위치 수가 늘어날수록 계산량은 커지지만 남은 토큰이 더 많은 문맥을 활용해 품질이 높아집니다.
python
tracked_completion = track_completion()(litellm.completion)

def generate(prompt: str, model: str, **kwargs) -> dict:
    t0 = time.time()
    resp = tracked_completion(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        **kwargs,
    )
    return {
        "text": resp.choices[0].message.content or "",
        "latency_s": time.time() - t0,
        "output_tokens": getattr(resp.usage, "completion_tokens", None),
    }

LiteLLM 호출을 Opik으로 추적해 모델 응답과 함께 지연 시간 및 출력 토큰 수를 기록합니다.

python
class CodePasses(base_metric.BaseMetric):
    def __init__(self, name: str = "code_passes"):
        self.name = name

    def score(self, output: str, test: str, **kwargs):
        try:
            scope = {}
            exec(extract_code(output), scope)
            exec(test, scope)
            passed = True
        except Exception:
            passed = False
        return score_result.ScoreResult(name=self.name, value=1.0 if passed else 0.0)

생성된 Python 코드에서 Markdown fence를 제거한 뒤 테스트를 실행하고 통과 여부를 0 또는 1로 기록합니다.

Opik의 Mercury 2 평가 실행 화면에서 code_passes, latency_s, output_tokens 집계값과 개별 code-generation task 결과를 확인할 수 있습니다.
Screenshot화면에는 평균 code_passes 0.94, latency_s 4.31, output_tokens 658.88이 표시되고 각 요청의 duration, total tokens, feedback score가 표로 기록됩니다. Opik이 모델 호출을 tracing하고 품질·지연 시간·출력량을 함께 비교하는 평가 인프라로 쓰인다는 점을 나타냅니다.
Opik Experiments 화면에서 Mercury 2와 Claude Haiku 4.5를 포함한 여러 실험의 평균 duration과 feedback score를 나란히 비교합니다.
Screenshot실험 목록은 모델별 실행 결과를 동일한 dataset과 feedback score 기준으로 관리하며 Mercury 2의 여러 reasoning 설정을 구분합니다. 기사의 production 모델 비교가 단일 응답이 아니라 반복 실행과 집계된 실험 결과에 기반한다는 점을 보완합니다.
05
Production 환경의 비교에서는 Inception의 Mercury 2와 Claude Haiku 4.5를 30개 code-generation task에 적용하고, 20회 실행 평균의 pass rate와 end-to-end latency를 Opik trace로 수집했습니다. Mercury 2는 평균 3.0초에 84%를 통과했고 Haiku는 6.0초에 99.7%를 통과했으며, 난이도별로는 easy에서 둘 다 100%, medium에서 Mercury 2가 89%, hard에서 60%로 떨어졌습니다. Mercury 2의 속도는 easy 1.9초 대 3.5초, hard 4.5초 대 8.8초로 모든 난이도에서 유지됐지만, 출력 토큰 수는 689 대 714로 거의 같았습니다.
Mercury 2와 Claude Haiku 4.5의 easy, medium, hard task pass rate를 비교한 막대그래프입니다.
Chart두 모델은 easy에서 모두 100%이고 medium에서는 Mercury 2가 89%, Haiku가 100%이며 hard에서는 각각 60%와 99%입니다. Mercury 2의 품질 격차가 모든 작업에 고르게 발생하는 것이 아니라 hard task에서 집중된다는 평가 결과를 시각화합니다.
난이도별 Mercury 2와 Claude Haiku 4.5의 평균 응답 latency를 비교한 막대그래프입니다.
ChartMercury 2의 latency는 easy 1.9초, medium 2.9초, hard 4.5초이고 Haiku는 각각 3.5초, 6.2초, 8.8초입니다. Diffusion 모델의 속도 이점이 모든 난이도에서 유지되며 hard task에서 격차가 더 커진다는 점을 보여줍니다.
06
Mercury 2의 reasoning_effort를 instant, low, medium, high로 조정한 결과 hard-task pass rate는 앞의 세 설정에서 약 58%에 머물다가 high에서 83%로 상승했습니다. 이 변화와 함께 latency는 약 4.5초에서 7.1초로 늘었고, easy와 medium에서는 높은 effort가 결과를 거의 바꾸지 않아 추가 계산이 지연 시간으로 남았습니다. 따라서 Diffusion LM은 짧고 병렬화하기 쉬우며 latency가 중요한 code completion, on-device inference, high-throughput serving에 적합하지만, 긴 의존적 생성과 token-by-token streaming에서는 Autoregressive model의 장점이 커집니다.
Mercury 2의 reasoning_effort 설정별 hard-task latency와 pass rate를 함께 나타낸 막대·선 그래프입니다.
Chartinstant, low, medium의 hard-task pass rate는 58%, 60%, 57% 수준이지만 high에서 83%로 상승하고 latency는 7.1초까지 증가합니다. 추가 계산이 낮은 effort 구간에서는 거의 효과가 없다가 high에서만 정확도를 크게 높인다는 비연속적인 tradeoff를 나타냅니다.

용어 해설

마스크 확산(Masked Diffusion)
텍스트의 일부 토큰을 [MASK]로 바꾼 뒤 원래 토큰을 복원하도록 학습하는 Diffusion 방식입니다. 마스킹 비율을 0%에서 100%까지 바꿔가며 양방향 문맥에서 복원하는 능력을 익히고, 완전히 가려진 시퀀스에서 시작해 여러 단계로 토큰을 공개하며 텍스트를 생성합니다. 병렬 처리와 반복적인 수정이 핵심입니다.
자기회귀 생성(Autoregressive Generation)
모델이 이전에 생성한 토큰을 문맥으로 사용해 왼쪽에서 오른쪽으로 한 토큰씩 출력하는 생성 방식입니다. 이미 출력한 토큰은 이후 단계에서 수정하지 않으므로 순차 처리 비용이 발생하지만, 토큰 간 의존성을 직접 반영할 수 있습니다. 긴 추론이나 높은 정확도가 필요한 작업에서 Diffusion 방식과 비교되는 기준이 됩니다.
조건부 독립 가정(Conditional Independence)
Diffusion 모델이 한 번의 denoising 단계에서 여러 가려진 위치의 토큰을 현재 시퀀스가 주어진 조건 아래 서로 독립적으로 예측한다고 보는 가정입니다. 이 가정 덕분에 여러 위치를 병렬로 처리할 수 있지만, 자연어 토큰 사이의 실제 의존성이 강하면 품질이 낮아집니다. 한 단계에서 공개하는 토큰 수와 속도·정확도 사이의 균형을 결정합니다.
노이즈 제거(Denoising)
손상된 입력에서 원래 정보를 복원하는 역방향 처리 과정입니다. 이미지 Diffusion에서는 Gaussian noise를 제거하고, 텍스트 Diffusion에서는 [MASK] 토큰을 원래 토큰으로 바꿉니다. 모델은 현재까지 공개된 토큰과 남은 마스크를 함께 참고해 확신이 높은 예측부터 다음 단계의 문맥으로 확정합니다.
마스크 언어 모델링(Masked Language Modeling)
문장 일부를 [MASK]로 가린 뒤 양쪽 문맥을 사용해 원래 토큰을 예측하도록 학습하는 목표입니다. BERT는 주로 약 15%의 고정된 마스킹 비율을 사용하지만, masked diffusion은 0%에서 100% 사이의 다양한 마스킹 수준을 학습합니다. 이 확장을 통해 빈칸 채우기 중심의 표현 학습 목표가 생성 모델의 학습 목표로 바뀝니다.

기술

  • GPT-3.5
  • ChatGPT
  • GPT-5.6
  • Gemini Diffusion
  • DiffusionGemma
  • Gemma 4
  • LLaDA 1.5
  • BERT
  • Mercury 2
  • Claude Haiku 4.5
  • Opik
  • LiteLLM
  • PyTorch
  • Transformer

활용 사례

  • Code completion
  • On-device inference
  • High-throughput serving
  • Infilling
  • Constrained generation
  • 수정이 필요한 수학 및 코드 작업
  • Production LLM 품질·지연 시간 평가

언급된 리소스

AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

원문 발행 2026. 08. 27.수집 2026. 08. 27.출처 타입 RSS

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.