Paper Feed

Issue 23 · Project 06 GitHub AI / ML ✓ read

divelab/OPDLM

TL;DR: OPDLM converts a pretrained autoregressive Qwen3 (0.6B–8B) into a block-diffusion language model by having the student generate its own diffusion trajectories and distilling the AR teacher's distribution onto them — on-policy distillation rather than teacher-forced conversion. It's interesting because it attacks the main practical objection to diffusion LMs (you can't afford to pretrain one) with a ~62K-example recipe, and it ships code, data, init checkpoints, and eval harness under MIT. Caveat up front: the README contains zero benchmark numbers, and the trained paper checkpoints appear not to be uploaded yet.

What it is and why it matters

The AR-vs-diffusion LM debate is stuck on economics: diffusion LMs promise parallel decoding within blocks, but nobody wants to pretrain one from scratch at useful scale. Prior conversion work (SDAR, which this builds on) retrofits a pretrained AR model into a block-diffusion (BD3LM-style) model, but typically with off-policy, teacher-forced training: the student learns to denoise text sampled from the data or the teacher, not from its own generation process. That's the classic exposure-bias setup — the student never trains on the states it actually visits at inference.

OPDLM's move is to make the conversion on-policy: the student rolls out its own block-diffusion generations (128 tasks per rollout, max rollout length ramping 100→4000 tokens over the first 100 steps), and the loss is a forward KL between the AR teacher's next-token distribution and the student's denoising distribution at those self-generated states. At 0.6B/1.7B they use full-vocabulary KL; at 4B/8B they switch to Nemotron-style sparse KL over the teacher's top-16 tokens, which is a sensible memory trick worth stealing. One state per block, block_size=4, denoising_steps=4.

Qwen3 (AR) causal attention A2D convert BD3LM student init bidirectional attention Student rollouts block diffusion, own states generate (on-policy) Frozen AR teacher scores same states Forward KL top-16 @ 4B/8B Only 61,816 prompts (math / code / STEM / chat) drive the whole conversion
The student is distilled on states it generates itself, closing the train/inference distribution gap that plagues teacher-forced AR→diffusion conversion.

The student init is mechanical: convert_qwen_to_bd3lm.py takes a Qwen3 checkpoint and flips causal attention to bidirectional; pre-converted 4B/8B inits are on HF. Dynamic-threshold remasking is a pure inference-time knob (training runs with it off).

What's actually there

  • Code: full training (rl.py, DeepSpeed ZeRO-3, accelerate configs) and evaluation (pure_inference/eval.py handles both diffusion and AR backbones). Built on SDAR and TraceRL.
  • Data: opdlm_train (61,816 rows: TACO/KodCode/AceCode, DAPO, Nemotron-v2 math/STEM/chat) and eval data for 19 of 20 paper benchmarks on HF; Codeforces built via a script.
  • Checkpoints: A2D init models (4B/8B) are up. Section 3 claims trained 0.6B–8B checkpoints are in the collection, but Section 5 says paper checkpoints "will land... when released" and tells you to train your own. Check the collection before assuming.
  • Evidence: the README reports no numbers at all — no Table 1 excerpts, no speedups, no comparison to Qwen3 baselines or to TraDo (the math post-training comparison in Table 5). Everything quantitative lives in the arXiv paper (2606.06712). The repro table is thorough (main results, zero-shot thinking, multilingual, math post-training vs TraDo, 0.6B/1.7B scaling ablations, decoding sweeps), which is a good sign for reproducibility, but you must read the paper to know if the conversion regresses reasoning — the classic failure mode of A2D work.

Expectations

Paper-quality reproduction wants 8×H200 for training; eval runs on a single node data-parallel. Env setup is fussy (torch→requirements→flash-attn ordering, DS_SKIP_CUDA_CHECK=1 for CUDA minor mismatches). Launchers hardcode the authors' paths and SBATCH headers. block_size=4 with 4 denoising steps is small — don't expect dramatic parallel-decoding speedups at that setting; the win claimed is data efficiency of conversion, not raw throughput. 22 stars, MIT, actively updated.

Try it

Fastest path if the trained checkpoints are in the HF collection:

huggingface-cli download divelab/opdlm_eval_data --local-dir data/ --repo-type dataset

python pure_inference/eval.py \
  --models <ckpt_path> --model_bases bd3lm \
  --datasets HumanEval MBPP MATH500 GSM8K AIME2024 \
  --max_token 2048 --temperature 0.0 \
  --remasking_strategy low_confidence_static \
  --block_size 4 --denoising_steps_per_block 4 \
  --out_dir pure_inference/results

Run run_eval_greedy_4B_qwen.sh alongside for the AR baseline — that head-to-head on MATH500/HumanEval is the first thing worth checking.