Read the Code in This Order
The files are split by runtime responsibility. For a new model, read the request path first:registry.pychooses the model family, sampling params, and pipeline config.configs/pipeline_configs/{model}.pydefines model-specific denoising and decoding behavior.runtime/pipelines/{model}.pywires modules into stages.runtime/pipelines_core/stages/runs the shared stage logic.runtime/models/contains native model components only when the architecture cannot be reused.
runtime/models/ owns modeling code: checkpoint-defined neural modules,
architecture wrappers, and weight-loading or forward-path details that are
intrinsic to one model family. Reusable serving infrastructure belongs in
SGLang-Diffusion runtime folders such as runtime/cache/,
runtime/distributed/, runtime/utils/, or shared pipeline stages. This
includes cache managers, graph runners, process-group transport, request
utilities, and common action-policy helpers. Model packages may call these
helpers. Keep ownership in shared runtime folders unless the code is truly
architecture-specific.
Out-of-Tree Models and Pipelines
An installed package can register native component models and a pipeline without modifying SGLang-Diffusion. Register them in the package’s__init__.py:
- The string form of
register_modelkeeps component imports lazy. hf_model_pathsalso supports checkpoints withoutmodel_index.json. Other Diffusers checkpoints can select the pipeline through_class_name.- For a standalone safetensors file, pass
--pipeline CustomPipeline. - Set the environment variable before startup. Each process imports the package
once. Use
overwrite=Trueonly to intentionally replace a built-in pipeline.
Start With the Smallest Change
Before adding files, decide which path fits the model.
Do not add a folder just to mirror the Diffusers repository layout. Add a new
file only when an existing pipeline, stage, module, config, or sampler cannot
express the behavior clearly.
Minimal File Map
The source tree is split by runtime responsibility. That split is useful for optimization. Keep new model PRs focused on the files required by model behavior.
For a new native architecture, the common minimum is:
registry.pyconfigs/sample/{model}.pyconfigs/pipeline_configs/{model}.pyruntime/pipelines/{model}.pyruntime/models/dits/{model}.py
runtime/models/. Prefix caches,
request-local contexts, denoising graph runners, OpenPI-compatible transport,
and prefix/action process-group utilities should be shared SGLang-Diffusion
runtime infrastructure when they are useful beyond the first model.
Read the Reference First
Use the model’s Diffusers pipeline, official implementation, ormodel_index.json as the source of truth. Write down:
- Which modules must be loaded: tokenizer, text encoder, image encoder, transformer, scheduler, VAE, processor, and any extra adapters.
- The prompt and image encoding flow.
- Latent shape, packing, scale, shift, dtype, and device rules.
- Timestep and sigma schedule.
- The exact
forward()kwargs expected by the denoising network. - VAE decode rules and output post-processing.
Choose a Pipeline Shape
SGLang-Diffusion usesComposedPipelineBase to wire stages together. Most
native pipelines should choose the least invasive stage shape that preserves the
runtime semantics.
Prefer this order:
- Use native stages directly. This keeps the model on shared code paths for offload, component readiness, profiling, disaggregation, batching, and future stage-level optimizations.
- Subclass the narrowest native stage. If only prompt processing differs,
inherit from
TextEncodingStage. If only latent setup, timestep setup, denoising, or decode differs, inherit from that specific native stage. Preserve the existing input/output fields whenever possible. - Add a custom single-purpose stage only when no native stage contract fits. Keep the stage owner narrow: one stage should own one coherent transformation, such as a custom condition assembly step or a model-specific policy/action bridge.
- Use an aggregated
BeforeDenoisingStageonly as a last resort. This is the least preferred shape because it hides multiple runtime responsibilities in one stage, increases code size and review cost, and bypasses shared hooks for offload, profiling, disaggregation, batching, and future stage-level optimizations.
Implement the Pieces
1. Sampling Params
Create request parameters only for values users can set at runtime.2. Pipeline Config
PipelineConfig is where shared denoising and decoding stages get model-specific
callbacks.
forward() signature exactly.
3. Pipeline Wiring
Use the standard helper when the model fits it.TextEncodingStage directly.
BeforeDenoisingStage only when the reference pipeline couples
several preparation steps so tightly that splitting them would require fragile
duplicate state or extra synchronization. Do not start with this shape.
4. Last-Resort Before-Denoising Stage
ABeforeDenoisingStage is not a catch-all replacement for the native stages.
Use it when the model has custom latent packing, conditioning assembly, timestep
preparation, or request-local state that does not fit LatentPreparationStage or
TimestepPreparationStage, and only after checking whether the work can be a
native-stage subclass or a custom single-purpose stage. If the difference is
prompt handling, subclass TextEncodingStage instead.
A proper BeforeDenoisingStage should populate the batch fields consumed by
DenoisingStage.
DenoisingStage:
5. Distributed and memory integration
Single-GPU parity is only the first milestone. Complete native support also requires:- Encoder and DiT TP/SP: use native parallel projections and sharded weight
loading for TP, and
USPAttentionfor SP. Handle masks, RoPE, padding, and output gathering without falling back to a replicated full model. TP and SP must work together. - VAE parallel decode: subclass
ParallelTiledVAE, or reuse an existing native base with the same contract. Support tiled andspatial_sharddecode throughDecodingStageand the shared decode group. Reuseruntime/layers/parallel_conv.pyandruntime/models/vaes/parallel/diffusers_spatial.pywhere applicable. - Layerwise offload: every loaded neural module must inherit
LayerwiseOffloadableModuleMixinand list all repeated block paths inlayer_names. Setlayerwise_offload_dit_group_enabled = Falsefor non-DiT modules. Component CPU offload is not a substitute.
wanvideo.py and qwen_image.py for DiT TP/SP, gemma_3.py for encoder TP
and offload, and autoencoder_kl_qwenimage.py or ltx_2_vae.py for VAE decode.
The Diffusers backend is compatibility-first and does not need to meet this
native integration contract.
6. Registry
Register the family once the sampling params and pipeline config exist.EntryClass; do not add a second
pipeline registry unless the existing registry requires it.
Verify the Port
Use one deterministic prompt and seed while comparing with the reference implementation.- Run a single-GPU smoke test and check that the output contains coherent content.
- Compare latent scale and shift, timestep order, sigma values, and conditioning kwargs against Diffusers or the official implementation.
- Compare VAE decode separately, including tiled and multi-GPU
spatial_shard. - Run encoder and DiT TP, SP, combined TP x SP, and
--layerwise-offload-components all; compare with the single-GPU resident baseline. - If the model supports LoRA, CFG parallelism, or disaggregation, test each feature explicitly.
- Add or update the cookbook, examples, and Supported Models catalog when users need a new launch command.
- Wrong latent scale or shift.
- Reversed or dtype-mismatched timesteps.
- Missing negative embeddings when CFG is enabled.
- Conditioning kwarg names mismatched with the DiT
forward(). - Rotary embedding shape or style mismatch.
- Decoding packed latents without restoring
raw_latent_shape.
PR Checklist
- Reused an existing family, stage, module, scheduler, or VAE wherever possible.
- Kept the new-model touch surface small and justified any extra files.
- Added
SamplingParams,PipelineConfig, pipeline wiring, DiT module, and registry entry when native support is needed. - Confirmed
pipeline_namematches the Diffusersmodel_index.json_class_namewhen applicable. - Confirmed
_required_config_modulesmatches the model repo. - Verified image or video quality against a reference output.
- Completed the distributed and memory integration checks above.
- Tested CFG parallelism and distributed serving paths when they apply.
