7.3 KiB
Troubleshooting Reference
Common Errors When Adding a Diffusion Model
ImportError / ModuleNotFoundError
Cause: Missing or incorrect registration.
Fix checklist:
- Model registered in
vllm_omni/diffusion/registry.py_DIFFUSION_MODELSdict __init__.pyexports the pipeline class- Pipeline file exists at the correct path:
vllm_omni/diffusion/models/{folder}/{file}.py - Class name in registry matches the actual class name in the file
Shape Mismatch in Attention
Symptom: RuntimeError: shape mismatch or expected 4D tensor
Cause: QKV tensors not reshaped to [batch, seq_len, num_heads, head_dim].
Fix: Before calling self.attn(q, k, v, ...), ensure:
q = q.view(batch, seq_len, self.num_heads, self.head_dim)
k = k.view(batch, kv_seq_len, self.num_kv_heads, self.head_dim)
v = v.view(batch, kv_seq_len, self.num_kv_heads, self.head_dim)
After attention, reshape back:
out = out.reshape(batch, seq_len, -1)
Weight Loading Failures
Symptom: RuntimeError: size mismatch for parameter ... or missing keys
Debugging:
- Print diffusers weight names:
safetensors.safe_open(path, "pt").keys() - Print model parameter names:
dict(model.named_parameters()).keys() - Compare and add name remappings in
load_weights()
Common remappings needed:
ff.net.0.proj→ff.net_0.proj(PyTorch Sequential indexing).to_out.0.→.to_out.(Sequential unwrapping)scale_shift_table→ moved to a wrapper module
Black/Blank/Noisy Output
Possible causes:
- Wrong latent normalization: Check VAE expects latents scaled by
vae.config.scaling_factor - Wrong scheduler: Using the wrong scheduler class or wrong
flow_shift - Missing CFG: Some models require
guidance_scale > 1.0with negative prompt - Wrong timestep format: Some schedulers expect float, others expect int/long
- Missing post-processing: Raw VAE output may need denormalization
Quick test: Run with diffusers directly using the same seed and compare latents at each step.
OOM (Out of Memory)
Solutions (in order of preference):
--enforce-eagerto disable torch.compile (saves compile memory)--enable-cpu-offloadfor model-level offload--enable-layerwise-offloadfor block-level offload (better for large models)--vae-use-slicing --vae-use-tilingfor VAE memory reduction- Reduce resolution:
--height 480 --width 832 - Use TP:
--tensor-parallel-size 2
Different Output vs Diffusers Reference
Common causes:
- Attention backend difference: FlashAttention vs SDPA may produce slightly different results. Set
DIFFUSION_ATTENTION_BACKEND=TORCH_SDPAto match diffusers - Float precision: vLLM-Omni may use bfloat16 where diffusers uses float32 for some operations
- Missing normalization: Check all LayerNorm/RMSNorm are preserved
- Scheduler rounding: Some schedulers have numerical sensitivity
Tensor Parallel Errors
Symptom: AssertionError: not divisible or incorrect output with TP>1
Fix:
- Verify
num_heads % tp_size == 0andnum_kv_heads % tp_size == 0 - Ensure
ColumnParallelLinear/RowParallelLinearare used correctly - Check that norms between parallel layers use distributed norm if needed
- Verify
load_weightshandles TP sharding for norm weights - Use
self.to_qkv.num_heads(local heads per GPU) for QKV split sizes, not total heads
Missing input_is_parallel=True:
RowParallelLinear expects sharded input from ColumnParallelLinear:
self.w1 = ColumnParallelLinear(dim, hidden_dim, return_bias=False)
self.w2 = RowParallelLinear(hidden_dim, dim, input_is_parallel=True, return_bias=False)
Sequence Parallel Errors
Symptom: Incorrect output or crashes with --ulysses-degree N or --usp N
Possible causes:
- Inline operations between shard/gather points:
torch.cat(),pad_sequence()etc. not atnn.Moduleboundaries. Fix: extract into submodule. - Wrong
split_dim: Check the tensor shape at the shard point. Sequence dimension is typicallydim=1for[B, S, D]tensors. - RoPE not sharded: If RoPE is computed separately, add it to
_sp_planwithsplit_output=True. - Sequence not divisible by SP degree: Use
auto_pad=TrueinSequenceParallelInputor switch toulysses_mode="advanced_uaa".
Debugging: Add expected_dims=N to SequenceParallelInput/Output for shape validation at runtime.
CFG Parallel Errors
Symptom: CFG parallel not activating, no speedup
Fix checklist:
- Pipeline inherits
CFGParallelMixin guidance_scale > 1.0- Negative prompt provided (even if empty string)
--cfg-parallel-size 2specifieddiffuse()method callspredict_noise_maybe_with_cfg()andscheduler_step_maybe_with_cfg()
Symptom: Different output with CFG parallel vs sequential
Possible cause: Non-deterministic scheduler. Fix: pass generator=torch.Generator(device).manual_seed(seed) to scheduler_step_maybe_with_cfg().
HSDP Errors
Symptom: HSDP not activating or errors during weight loading
Fix checklist:
- Transformer defines
_hsdp_shard_conditionsclass attribute - Shard condition functions return
Truefor correct modules (test withmodel.named_modules()) - Not combining with TP (HSDP and TP are incompatible)
- For standalone HSDP,
hsdp_shard_sizeis specified explicitly
Verify: Check logs for "HSDP Inference: replicate_size=..., shard_size=..." and "Sharded N modules + root".
Cache-DiT Not Applied
Symptom: No speedup, no cache-related log messages
Fix checklist:
- Model not in
_NO_CACHE_ACCELERATIONinregistry.py - Pipeline class name matches
CUSTOM_DIT_ENABLERSkey (if using custom enabler) cache_backend="cache_dit"specified- Check logs for "Cache-dit enabled successfully on xxx"
Verify pipeline name: print(pipeline.__class__.__name__) — must match registry key.
Cache-DiT Quality Degradation
Symptom: Artifacts or lower quality with cache-dit
Fix: Reduce aggressiveness:
cache_config={
"residual_diff_threshold": 0.12, # Lower from 0.24
"max_warmup_steps": 6, # Increase from 4
"max_continuous_cached_steps": 2, # Reduce if higher
}
If quality is still poor, the model may need a custom enabler with per-block-list ParamsModifier tuning.
Model Not Detected / Wrong Pipeline Class
Symptom: ValueError: Model class ... not found in diffusion model registry
Cause: The model's model_index.json has a _class_name for the pipeline that doesn't match registry keys.
Fix: The registry key must match the diffusers pipeline class name from model_index.json. If using a different name, map it in the registry:
"DiffusersPipelineClassName": ("your_folder", "your_file", "YourVllmClassName"),
Debugging Workflow
- Add verbose logging: Use
logger.info()to print tensor shapes at each stage - Compare step-by-step: Run diffusers and vllm-omni side by side, comparing tensors after each major operation
- Use small configs: Reduce
num_inference_steps=2, small resolution for fast iteration - Test transformer isolation: Feed the same input to both diffusers and vllm-omni transformers, compare outputs
- Binary search for bugs: Comment out blocks/layers to isolate where divergence starts