Back to skills
SKILL.md
Discrete Diffusion Faster Inference
ASecurityEnables diffusion LLMs to achieve 2.5× faster inference than autoregressive models through block-wise generation with parallel inter-block decoding.
- 6 stars
- 0 votes
- 0 copies
- 1 view
- Added September 9, 2026
Works with
Security analysis
100/100npx -y skills add ADu2021/skillXiv --skill discrete-diffusion-faster-inference --agent claude-codeAre you the author of Discrete Diffusion Faster Inference?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/adu2021-discrete-diffusion-faster-inference)---
name: discrete-diffusion-faster-inference
title: Diffusion LLMs Can Do Faster-Than-AR Inference via Discrete Diffusion Forcing
version: 0.0.2
engine: skillxiv-v0.0.2-claude-opus-4.6
license: MIT
url: https://arxiv.org/abs/2508.09192
keywords: [diffusion-language-models, fast-inference, parallel-decoding, discrete-diffusion]
description: "Enables diffusion LLMs to achieve 2.5× faster inference than autoregressive models through block-wise generation with parallel inter-block decoding."
---
## Diffusion LLMs Can Do Faster-Than-AR Inference via Discrete Diffusion Forcing
### Core Concept
Discrete Diffusion Forcing (D2F) enhances diffusion-based LLMs to achieve faster inference than autoregressive models by combining block-wise autoregressive generation (enabling KV cache) with inter-block parallel decoding. This hybrid approach leverages the parallelization potential of diffusion models while maintaining efficiency mechanisms of AR models.
### Architecture Overview
- **Block-Wise Autoregressive**: KV cache utilization within blocks
- **Inter-Block Parallel Decoding**: Predict multiple blocks in parallel
- **Asymmetric Distillation**: Train from pre-trained diffusion models
- **Pipelined Execution**: Overlap computation across blocks
### Implementation Steps
**Step 1: Design Block-Wise Generation**
Implement block-based generation:
```python
class BlockWiseGenerator:
def __init__(self, diffusion_model, block_size=32):
super().__init__()
self.model = diffusion_model
self.block_size = block_size
def generate_with_blocks(self, prompt, max_blocks=10):
"""Generate text in blocks with KV caching."""
generated_blocks = []
kv_cache = None
for block_idx in range(max_blocks):
# Generate single block
block = self._generate_block(prompt, block_idx, kv_cache)
if block is None:
break
generated_blocks.append(block)
# Update cache
if kv_cache is None:
kv_cache = block['cache']
else:
kv_cache = self._merge_caches(kv_cache, block['cache'])
return ''.join([b['text'] for b in generated_blocks])
def _generate_block(self, prompt, block_idx, kv_cache):
"""Generate single block with AR within block."""
block_tokens = []
for token_in_block in range(self.block_size):
# Use KV cache from previous blocks
with torch.no_grad():
outputs = self.model(
prompt + ''.join(block_tokens),
kv_cache=kv_cache
)
# AR sampling within block
logits = outputs.logits[:, -1, :]
next_token = torch.multinomial(F.softmax(logits, dim=-1), 1)
block_tokens.append(next_token.item())
return {
'text': ''.join(block_tokens),
'tokens': block_tokens,
'cache': outputs.past_key_values
}
```
**Step 2: Implement Parallel Inter-Block Decoding**
Enable parallel block prediction:
```python
class ParallelBlockDecoder:
def __init__(self, diffusion_model, num_parallel_blocks=3):
super().__init__()
self.model = diffusion_model
self.num_parallel = num_parallel_blocks
def generate_parallel(self, prompt, max_blocks=20):
"""Generate multiple blocks in parallel."""
import asyncio
import concurrent.futures
all_blocks = []
block_futures = []
with concurrent.futures.ThreadPoolExecutor(max_workers=self.num_parallel) as executor:
# Submit first batch of blocks
for block_idx in range(self.num_parallel):
future = executor.submit(
self._generate_block_parallel,
prompt,
block_idx
)
block_futures.append((block_idx, future))
# Collect results and submit new blocks
block_idx = self.num_parallel
while block_futures:
completed_futures = []
for idx, future in block_futures:
if future.done():
block = future.result()
all_blocks.append((idx, block))
completed_futures.append((idx, future))
# Submit next block
if block_idx < max_blocks:
new_future = executor.submit(
self._generate_block_parallel,
prompt + self._construct_prefix(all_blocks),
block_idx
)
block_futures.append((block_idx, new_future))
block_idx += 1
# Remove completed futures
for item in completed_futures:
block_futures.remove(item)
# Sort by index and concatenate
all_blocks.sort(key=lambda x: x[0])
return ''.join([b[1]['text'] for b in all_blocks])
def _generate_block_parallel(self, prompt, block_idx):
"""Generate block (for parallel execution)."""
block_tokens = []
for token_in_block in range(32):
with torch.no_grad():
outputs = self.model(prompt + ''.join(block_tokens))
logits = outputs.logits[:, -1, :]
next_token = torch.multinomial(F.softmax(logits, dim=-1), 1)
block_tokens.append(next_token.item())
return {
'text': ''.join(block_tokens),
'block_idx': block_idx
}
def _construct_prefix(self, completed_blocks):
"""Construct prefix from completed blocks."""
return ''.join([b[1]['text'] for b in sorted(completed_blocks, key=lambda x: x[0])])
```
**Step 3: Implement Asymmetric Distillation**
Train D2F models:
```python
class AsymmetricDistillation:
def __init__(self, teacher_model, student_model):
super().__init__()
self.teacher = teacher_model
self.student = student_model
def distill(self, training_data, num_epochs=3):
"""Distill teacher to student with D2F training."""
optimizer = AdamW(self.student.parameters(), lr=1e-4)
for epoch in range(num_epochs):
total_loss = 0
for batch in training_data:
# Teacher generates reference
with torch.no_grad():
teacher_outputs = self.teacher(batch['input_ids'])
teacher_logits = teacher_outputs.logits
# Student generates with D2F
student_outputs = self.student(batch['input_ids'])
student_logits = student_outputs.logits
# KL divergence loss
loss = F.kl_div(
F.log_softmax(student_logits, dim=-1),
F.softmax(teacher_logits, dim=-1),
reduction='batchmean'
)
optimizer.zero_grad()
loss.backward()
torch.nn.utils.clip_grad_norm_(self.student.parameters(), 1.0)
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}: Loss = {total_loss / len(training_data):.4f}")
return self.student
```
**Step 4: Benchmark Inference Speed**
Measure speedup:
```python
class InferenceSpeedBenchmark:
def __init__(self, ar_model, diffusion_model, d2f_model):
super().__init__()
self.ar = ar_model
self.diffusion = diffusion_model
self.d2f = d2f_model
def benchmark(self, prompts, max_tokens=256):
"""Compare inference speeds."""
import time
results = {}
# AR baseline
ar_times = []
for prompt in prompts:
start = time.time()
_ = self.ar.generate(prompt, max_length=max_tokens)
ar_times.append(time.time() - start)
results['ar'] = {
'avg_time': np.mean(ar_times),
'tokens_per_sec': max_tokens / np.mean(ar_times)
}
# Pure diffusion
diffusion_times = []
for prompt in prompts:
start = time.time()
_ = self.diffusion.generate(prompt, max_length=max_tokens)
diffusion_times.append(time.time() - start)
results['diffusion'] = {
'avg_time': np.mean(diffusion_times),
'tokens_per_sec': max_tokens / np.mean(diffusion_times)
}
# D2F (parallel blocks)
d2f_times = []
for prompt in prompts:
start = time.time()
_ = self.d2f.generate_parallel(prompt, max_blocks=max_tokens // 32)
d2f_times.append(time.time() - start)
results['d2f'] = {
'avg_time': np.mean(d2f_times),
'tokens_per_sec': max_tokens / np.mean(d2f_times),
'speedup_vs_ar': np.mean(ar_times) / np.mean(d2f_times)
}
return results
```
### Practical Guidance
**Hyperparameters and Configuration**:
- Block size: 32 tokens
- Parallel blocks: 3-5 depending on memory
- Distillation learning rate: 1e-4 to 5e-5
- KL divergence weight: 1.0
**When to Use D2F**:
- Inference speed critical applications
- Long sequence generation
- Batch inference scenarios
- Models with adequate parallel infrastructure
**When NOT to Use**:
- Single-token streaming (overhead > benefit)
- Real-time latency sensitive (block overhead)
- Memory constrained (multi-block caching)
**Implementation Notes**:
- Parallel blocks require sufficient memory for multiple KV caches
- Block size affects latency/throughput tradeoff
- Distillation critical for maintaining quality
- Monitor speedup vs quality degradation
### Reference
Paper: Diffusion LLMs Can Do Faster-Than-AR Inference via Discrete Diffusion Forcing
ArXiv: 2508.09192
Performance: 2.5× faster than LLaMA3/Qwen2.5, 50× faster than vanilla diffusion LLMs
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.