onediff

repository·main·Indexed 24 days ago

https://github.com/siliconflow/onediff

An acceleration library designed to speed up diffusion models such as SDXL, SVD, and DiT using optimized GPU kernels and PyTorch compilation tools. It integrates with HF diffusers and ComfyUI, providing specialized nodes for ControlNet, LoRA with DeepCache, and Stable Diffusion 3 (SD3) acceleration.

Tokens
32.7K
Snippets
92
Records
167
Agent score
84%

What's inside onediff

  1. Overview of OneDiff Enterprise

    main
    OneDiff Enterprise provides a quantization method designed to reduce memory usage and increase inference speed while maintaining model quality without loss. It is an advanced version of the OneDiff Community features. Before using Enterprise, it is recommended to understand the core OneDiff Community features.
  2. Overview of onediff

    main
    onediff (short for "one line of code to accelerate diffusion models") is an acceleration library for diffusion models. It provides out-of-the-box acceleration for popular libraries and UIs like HF diffusers and ComfyUI. It also includes PyTorch code compilation tools and optimized GPU kernels specifically designed for diffusion models.
  3. Key features and capabilities of onediff

    main

    onediff is an acceleration library for diffusion models with the following key characteristics:

    • Performance: Compilation time is approximately 1 minute for SDXL. LoRA switching takes hundreds of milliseconds, and LoRA occupancy ranges from tens to hundreds of MB.
    • Model & Algorithm Support: Supports SD1.5~2.1, SDXL, SDXL Turbo, etc. It works with standard SD workflows, LoRA, ControlNet, SVD, InstantID, and SDXL Lightning.
    • Framework Support: Compatible with ComfyUI, Diffusers, and SD-webui.
    • Flexibility: Supports dynamic image sizes with no overhead and provides plug-and-play deployment.
    • Hardware: Optimized for NVIDIA GPUs (3090 RTX, 4090 RTX, A100, A800, A10, etc.). Compatibility with Ascend is currently in progress.
  4. OneDiff Enterprise Solution

    main

    For businesses requiring enterprise-level support, the OneDiff Enterprise Solution provides:

    • Extreme Optimization: Additional 20%~30% or more performance gains through specialized compiler optimization.
    • Workflow Speedup: End-to-end workflow speedups that can reach 200%~300% performance gains.
    • Deployment Solutions: Conversion of workflows directly into online model APIs.
    • High Priority Support: Technical support for deployment.

    Contact: contact@siliconflow.com or visit https://siliconflow.cn/pricing.

  5. Re-use compiled graphs for faster model switching

    main

    If you are switching between models that share the same structure, you can re-use a previously compiled graph instead of re-compiling. This significantly reduces model switching time. To do this, load the new model's state dict into the _torch_module member of the object returned by oneflow_compile.

    Note: This feature is not supported for quantized models.

    base = StableDiffusionPipeline(...)
    compiled_unet = oneflow_compile(base.unet)
    base.unet = compiled_unet
    # This step needs some time to compile the UNet
    base(prompt)
    
    new_base = StableDiffusionPipeline(...)
    # Re-use the compiled graph by loading the new state dict into the `_torch_module` member of the object returned by `oneflow_compile`
    compiled_unet._torch_module.load_state_dict(new_base.unet.state_dict())
    # After loading the new state dict into the `compiled_unet._torch_module`, the weights of the compiled_unet are updated too
    new_base.unet = compiled_unet
    # This step doesn't need additional time to compile the UNet again because
    # new_base.unet is already compiled
    new_base(prompt)
  6. Enable dynamic shape support in Nexfort

    main

    The Nexfort backend supports out-of-the-box dynamic shape inference. To use it, set "dynamic": true in your options dictionary.

    Best Practice: To avoid over-specialization and frequent re-compilation, perform an initial call to your model with a non-typical shape (e.g., a height and width that are not equal, such as 512x768).

    Example Configuration

    options = '{"mode": "max-autotune", "dynamic": true}'

    CLI Usage Example (SDXL)

    python3 ./onediff_diffusers_extensions/examples/text_to_image_sdxl.py \
    --height 512 \
    --width 768 \
    --compiler nexfort \
    --compiler-config '{"mode": "max-optimize:max-autotune:low-precision", "memory_format": "channels_last", "dynamic": true}' \
    --run_multiple_resolutions 1 \
    --run_rare_resolutions 1
  7. Quantization in OneDiff

    main

    Quantization features (which reduce memory usage and increase speed while maintaining quality) are exclusively available to OneDiff Enterprise users.

    If you have a license key, refer to the Online Quantization for ComfyUI documentation for specific instructions on using quantized models.

  8. Understand OneDiff Online Quantization caching behavior

    main

    The first time you perform quantization, the system requires additional computation time to analyze data dependencies and identify necessary parameters (such as maximum and minimum values).

    Once these parameters are established, they are stored in a cache. Subsequent quantization processes will use these cached parameters, significantly accelerating processing speed.

    • Cached files: The log file *.pt is cached.
    • Quantization results: Information regarding quantization results can be found in cache_dir/quantization_stats.json.
  9. Use LoRA with OneDiff

    main

    OneDiff supports full LoRA functionality. You can use LoRAs exactly as you do with native Stable Diffusion WebUI.

    • Dynamic Switching: OneDiff supports switching LoRAs without recompiling the model because the model with and without LoRA share the same parameter pointer captured by the static graph.
    • Performance: Initial LoRA fusing may take 1-2 seconds, but subsequent fusions stabilize at approximately ~700ms. Fusing does not impact the model's inference efficiency.
  10. Fast LoRA loading and switching with OneDiffX

    main

    OneDiffX provides an optimized implementation for loading and fusing LoRA weights into Hugging Face Diffusers pipelines. It is designed to be faster than standard Diffusers or PEFT methods by directly fusing weights into the model, bypassing the overhead of module replacement (e.g., LoRACompatible or BaseTunerLayer).

    Best Practices for Multiple LoRAs

    If you need to load multiple LoRAs before inference, do not repeatedly call load_and_fuse_lora as it may cause precision issues. Instead:

    1. Call load_lora_and_optionally_fuse with fuse=False for each LoRA.
    2. Use set_and_fuse_adapters to apply them.

    Requirements

    • Supports Diffusers version 0.21.0 or higher.
    • Currently supports a limited subset of PEFT APIs.
  11. Accelerate Stable Diffusion with DeepCache

    main

    OneDiffX provides DeepCache speedup for Stable Diffusion models. To use it, import the specialized pipeline classes from onediffx.deep_cache instead of the standard diffusers classes.

    For Stable Diffusion XL

    Import StableDiffusionXLPipeline from onediffx.deep_cache.

    For Stable Diffusion 1.5

    Import StableDiffusionPipeline from onediffx.deep_cache.

    When calling the pipeline, use the following parameters to control DeepCache:

    • cache_interval: The interval between cache updates.
    • cache_layer_id: The layer ID to use for caching.
    • cache_block_id: The block ID to use for caching.

    Note: It is recommended to perform a 'warmup' run (running the pipeline once) before the actual inference to ensure the cache is properly initialized.

    import torch
    from onediffx import compile_pipe
    from onediffx.deep_cache import StableDiffusionXLPipeline
    
    pipe = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
        variant="fp16",
        use_safetensors=True
    )
    pipe.to("cuda")
    pipe = compile_pipe(pipe)
    
    # Warmup
    for i in range(1):
        deepcache_output = pipe(
            "A photo of a cat.",
            cache_interval=3, cache_layer_id=0, cache_block_id=0,
            output_type='pil'
        ).images[0]
    
    # Actual inference
    deepcache_output = pipe(
        "A photo of a cat.",
        cache_interval=3, cache_layer_id=0, cache_block_id=0,
        output_type='pil'
    ).images[0]