> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sglang.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Qwen-Image

export const QwenImageDeployment = () => {
  const config = {
    modelFamily: 'Qwen-Image',
    options: {
      hardware: {
        name: 'hardware',
        title: 'Hardware Platform',
        items: [{
          id: 'b200',
          label: 'B200',
          default: true
        }, {
          id: 'b300',
          label: 'B300',
          default: false
        }, {
          id: 'h200',
          label: 'H200',
          default: false
        }, {
          id: 'h100',
          label: 'H100',
          default: false
        }, {
          id: 'mi300x',
          label: 'MI300X',
          default: false
        }, {
          id: 'mi325x',
          label: 'MI325X',
          default: false
        }, {
          id: 'mi355x',
          label: 'MI355X',
          default: false
        }, {
          id: 'a2',
          label: 'A2 Series',
          default: false
        }, {
          id: 'a3',
          label: 'A3 Series',
          default: false
        }]
      },
      precision: {
        name: 'precision',
        title: 'Precision',
        items: [{
          id: 'bf16',
          label: 'BF16',
          default: true
        }, {
          id: 'nvfp4',
          label: 'NVFP4',
          default: false,
          disabledWhen: values => !['b200', 'b300'].includes(values.hardware),
          disabledReason: 'ModelOpt NVFP4 requires Blackwell hardware such as B200 or B300'
        }]
      }
    },
    generateCommand: function (values) {
      if (values.hardware === 'a2') {
        return `sglang serve \\
  --model-path Qwen/Qwen-Image \\
  --num-gpus 1`;
      }
      if (values.hardware === 'a3') {
        return `#One A3 Series card has 2 npu chips
sglang serve \\
  --model-path Qwen/Qwen-Image \\
  --tp-size 1 \\
  --sp-degree 2 \\
  --num-gpus 2`;
      }
      const isBlackwell = ['b200', 'b300'].includes(values.hardware);
      const isNvfp4 = values.precision === 'nvfp4' && isBlackwell;
      const modelPath = isNvfp4 ? 'lmsys/qwen-image-2512-modelopt-nvfp4-sglang' : 'Qwen/Qwen-Image';
      return `sglang serve \\
  --model-path ${modelPath} \\
  --ulysses-degree=1 \\
  --ring-degree=1`;
    }
  };
  if (!config || !config.options) {
    return <div>Error: Invalid configuration provided</div>;
  }
  const getInitialState = () => {
    const initialState = {};
    Object.entries(config.options).forEach(([key, option]) => {
      if (option.type === 'checkbox') {
        initialState[key] = (option.items || []).filter(item => item.default).map(item => item.id);
        return;
      }
      if (option.type === 'text') {
        initialState[key] = option.default || '';
        return;
      }
      let items = option.items || [];
      if (option.getDynamicItems) {
        const defaultValues = {};
        Object.entries(config.options).forEach(([innerKey, innerOption]) => {
          if (innerOption.type === 'checkbox') {
            defaultValues[innerKey] = (innerOption.items || []).filter(item => item.default).map(item => item.id);
          } else if (innerOption.type === 'text') {
            defaultValues[innerKey] = innerOption.default || '';
          } else if (innerOption.items && innerOption.items.length > 0) {
            const defaultItem = innerOption.items.find(item => item.default);
            defaultValues[innerKey] = defaultItem ? defaultItem.id : innerOption.items[0].id;
          }
        });
        items = option.getDynamicItems(defaultValues);
      }
      const defaultItem = items && items.find(item => item.default);
      initialState[key] = defaultItem ? defaultItem.id : items && items[0] ? items[0].id : '';
    });
    return initialState;
  };
  const [values, setValues] = useState(getInitialState);
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const checkDarkMode = () => {
      const html = document.documentElement;
      const isDarkMode = html.classList.contains('dark') || html.getAttribute('data-theme') === 'dark' || html.style.colorScheme === 'dark';
      setIsDark(isDarkMode);
    };
    checkDarkMode();
    const observer = new MutationObserver(checkDarkMode);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class', 'data-theme', 'style']
    });
    return () => observer.disconnect();
  }, []);
  useEffect(() => {
    let targetTabName = 'AMD MI300X';
    if (values.hardware === 'a2') targetTabName = 'Ascend A2 Series';
    if (values.hardware === 'a3') targetTabName = 'Ascend A3 Series';
    const allTabs = document.querySelectorAll('button, [role="tab"]');
    allTabs.forEach(tab => {
      const text = tab.textContent.trim();
      if (text === targetTabName && tab.getAttribute('aria-selected') !== 'true') {
        tab.click();
      }
    });
  }, [values.hardware]);
  const handleRadioChange = (optionName, value) => {
    setValues(prev => {
      const next = {
        ...prev,
        [optionName]: value
      };
      if (optionName === 'hardware' && !['b200', 'b300'].includes(value) && next.precision === 'nvfp4') {
        next.precision = 'bf16';
      }
      return next;
    });
  };
  const handleCheckboxChange = (optionName, itemId, isChecked) => {
    setValues(prev => {
      const currentValues = prev[optionName] || [];
      if (isChecked) {
        return {
          ...prev,
          [optionName]: [...currentValues, itemId]
        };
      }
      return {
        ...prev,
        [optionName]: currentValues.filter(id => id !== itemId)
      };
    });
  };
  const handleTextChange = (optionName, value) => {
    setValues(prev => ({
      ...prev,
      [optionName]: value
    }));
  };
  const command = config.generateCommand ? config.generateCommand.call(config, values) : '';
  const containerStyle = {
    maxWidth: '900px',
    margin: '0 auto',
    display: 'flex',
    flexDirection: 'column',
    gap: '4px'
  };
  const cardStyle = {
    padding: '8px 12px',
    border: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`,
    borderLeft: `3px solid ${isDark ? '#E85D4D' : '#D45D44'}`,
    borderRadius: '4px',
    display: 'flex',
    alignItems: 'center',
    gap: '12px',
    background: isDark ? '#1f2937' : '#fff'
  };
  const titleStyle = {
    fontSize: '13px',
    fontWeight: '600',
    minWidth: '140px',
    flexShrink: 0,
    color: isDark ? '#e5e7eb' : 'inherit'
  };
  const itemsStyle = {
    display: 'flex',
    rowGap: '2px',
    columnGap: '6px',
    flexWrap: 'wrap',
    alignItems: 'center',
    flex: 1
  };
  const labelBaseStyle = {
    padding: '4px 10px',
    border: `1px solid ${isDark ? '#9ca3af' : '#d1d5db'}`,
    borderRadius: '3px',
    cursor: 'pointer',
    display: 'inline-flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
    fontWeight: '500',
    fontSize: '13px',
    transition: 'all 0.2s',
    userSelect: 'none',
    minWidth: '45px',
    textAlign: 'center',
    flex: 1,
    background: isDark ? '#374151' : '#fff',
    color: isDark ? '#e5e7eb' : 'inherit'
  };
  const checkedStyle = {
    background: '#D45D44',
    color: 'white',
    borderColor: '#D45D44'
  };
  const disabledStyle = {
    cursor: 'not-allowed',
    opacity: 0.5
  };
  const subtitleStyle = {
    display: 'block',
    fontSize: '9px',
    marginTop: '1px',
    lineHeight: '1.1',
    opacity: 0.7
  };
  const textInputStyle = {
    flex: 1,
    padding: '8px 10px',
    borderRadius: '4px',
    border: `1px solid ${isDark ? '#4b5563' : '#d1d5db'}`,
    background: isDark ? '#111827' : '#fff',
    color: isDark ? '#e5e7eb' : '#111827',
    fontSize: '13px'
  };
  const commandDisplayStyle = {
    flex: 1,
    padding: '12px 16px',
    background: isDark ? '#111827' : '#f5f5f5',
    borderRadius: '6px',
    fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace",
    fontSize: '12px',
    lineHeight: '1.5',
    color: isDark ? '#e5e7eb' : '#374151',
    whiteSpace: 'pre-wrap',
    overflowX: 'auto',
    margin: 0,
    border: `1px solid ${isDark ? '#374151' : '#e5e7eb'}`
  };
  return <div style={containerStyle} className="not-prose">
      {Object.entries(config.options).map(([key, option]) => {
    if (option.condition && !option.condition(values)) {
      return null;
    }
    const items = option.getDynamicItems ? option.getDynamicItems(values) : option.items || [];
    return <div key={key} style={cardStyle}>
            <div style={titleStyle}>{option.title}</div>
            <div style={itemsStyle}>
              {option.type === 'text' ? <input type="text" value={values[option.name] || ''} placeholder={option.placeholder || ''} onChange={event => handleTextChange(option.name, event.target.value)} style={textInputStyle} /> : option.type === 'checkbox' ? (option.items || []).map(item => {
      const isChecked = (values[option.name] || []).includes(item.id);
      const isDisabled = item.required || typeof item.disabledWhen === 'function' && item.disabledWhen(values);
      return <label key={item.id} title={item.disabledReason || ''} style={{
        ...labelBaseStyle,
        ...isChecked ? checkedStyle : {},
        ...isDisabled ? disabledStyle : {}
      }}>
                      <input type="checkbox" checked={isChecked} disabled={isDisabled} onChange={event => handleCheckboxChange(option.name, item.id, event.target.checked)} style={{
        display: 'none'
      }} />
                      {item.label}
                      {item.subtitle && <small style={{
        ...subtitleStyle,
        color: isChecked ? 'rgba(255,255,255,0.85)' : 'inherit'
      }}>
                          {item.subtitle}
                        </small>}
                    </label>;
    }) : items.map(item => {
      const isChecked = values[option.name] === item.id;
      const isDisabled = item.disabled || typeof item.disabledWhen === 'function' && item.disabledWhen(values);
      return <label key={item.id} title={item.disabledReason || ''} style={{
        ...labelBaseStyle,
        ...isChecked ? checkedStyle : {},
        ...isDisabled ? disabledStyle : {}
      }}>
                      <input type="radio" name={option.name} value={item.id} checked={isChecked} disabled={isDisabled} onChange={() => !isDisabled && handleRadioChange(option.name, item.id)} style={{
        display: 'none'
      }} />
                      {item.label}
                      {item.subtitle && <small style={{
        ...subtitleStyle,
        color: isChecked ? 'rgba(255,255,255,0.85)' : 'inherit'
      }}>
                          {item.subtitle}
                        </small>}
                    </label>;
    })}
            </div>
          </div>;
  })}

      <div style={cardStyle}>
        <div style={titleStyle}>Run this Command:</div>
        <pre style={commandDisplayStyle}>{command}</pre>
      </div>
    </div>;
};

export const DiffusionModelTags = ({tags = []}) => {
  const normalizedTags = Array.isArray(tags) ? tags : [tags];
  return <div className="not-prose sgd-model-tags">
      {normalizedTags.map(tag => <span key={tag} className="sgd-chip">
          {tag}
        </span>)}
    </div>;
};

<DiffusionModelTags tags={["image", "text-to-image", "bilingual typography", "complex layouts", "NVFP4"]} />

## 1. Model Introduction

[Qwen-Image](https://huggingface.co/Qwen/Qwen-Image) is a 20B text-to-image model built for strong prompt following and precise rendering of English and Chinese text. It is especially useful for posters, signs, diagrams, and dense layouts where typography and spatial relationships matter as much as general image quality.

This page covers generation rather than editing: use Qwen-Image-Edit when an existing image, subject identity, or untouched region must be preserved. The full checkpoint is memory-heavy, while the validated ModelOpt NVFP4 release provides a supported low-precision deployment option with an expected quality tradeoff.

## 2. SGLang-diffusion Installation

SGLang-diffusion offers multiple installation methods. You can choose the most suitable installation method based on your hardware platform and requirements.

Please refer to the [official SGLang-diffusion installation guide](../../../docs/sglang-diffusion/installation) for installation instructions.

## 3. Model Deployment

This section provides deployment configurations optimized for different hardware platforms and use cases.

### 3.1 Basic Configuration

Qwen-Image is a text-to-image model. The recommended launch configurations vary by hardware. SGLang supports serving Qwen-Image on NVIDIA B200, B300, H200, H100, AMD MI300X, MI325X, MI355X GPUs and Ascend A2/A3 Series NPUs.

**Interactive Command Generator**: Use the configuration selector below to automatically generate the appropriate deployment command for your hardware platform.

<QwenImageDeployment />

For the validated ModelOpt NVFP4 checkpoint on Blackwell, load the published
Qwen-Image-2512 NVFP4 repo directly:

```bash Command theme={null}
sglang serve \
  --model-path lmsys/qwen-image-2512-modelopt-nvfp4-sglang \
  --ulysses-degree=1 \
  --ring-degree=1
```

For high-resolution B200 generations, the FlashInfer CUTLASS FP4 GEMM backend
can be faster than the default TensorRT-LLM FP4 GEMM backend:

```bash Command theme={null}
SGLANG_DIFFUSION_FLASHINFER_FP4_GEMM_BACKEND=cutlass \
sglang generate \
  --model-path lmsys/qwen-image-2512-modelopt-nvfp4-sglang \
  --width 2048 --height 2048 \
  --prompt "A tiny astronaut reading a book under a glass greenhouse" \
  --save-output
```

### 3.2 Fixed-resolution latency on two H200 GPUs

For `Qwen/Qwen-Image-2512` at 1024x1024, use breakable CUDA graph (BCG) to
reduce launch overhead across graph-safe DiT segments while retaining explicit
breakpoints around unsupported operations. This recipe was validated on two
NVIDIA H200 GPUs with 50 denoising steps and no classifier-free guidance:

```bash Command theme={null}
sglang serve \
  --model-path Qwen/Qwen-Image-2512 \
  --model-type diffusion \
  --num-gpus 2 \
  --tp-size 2 \
  --performance-mode speed \
  --dit-layerwise-offload false \
  --enable-torch-compile false \
  --enable-breakable-cuda-graph \
  --warmup-mode server \
  --warmup-resolutions 1024x1024
```

Declare every production resolution in `--warmup-resolutions`. A request at an
uncaptured resolution runs eagerly, so omitting `1024x1024` removes the gain
from this recipe. Graph capture used about 5 GB more peak memory per GPU in the
validation run.

On CUDA, the TP path dispatches supported collectives through SRT
CustomAllReduceV2. At 1024x1024, Qwen-Image reduces 24 MiB row-parallel
outputs; the diffusion runtime reserves a 32 MiB V2 workspace so these
collectives do not fall back to NCCL. If profiling shows large NCCL all-reduce
kernels again, first confirm that V2 is enabled and the requested shape fits
the workspace.

BCG changed floating-point execution order but not the sampling algorithm. The
fixed-seed output measured 0.984 SSIM and 39.7 dB PSNR against eager output; use
eager execution when you require bit-exact output. Regional `torch.compile` was
also tested on this profile and did not improve steady-state latency.

### 3.3 Configuration Tips

See [Performance Optimization](/docs/sglang-diffusion/performance-optimization) for acceleration features and their runtime requirements.

* `--vae-path`: Path to a custom VAE model or HuggingFace model ID (e.g., fal/FLUX.2-Tiny-AutoEncoder). If not specified, the VAE will be loaded from the main model path.
* `--num-gpus`: Number of GPUs to use
* `--tp-size`: Tensor parallelism size (only for the encoder; should not be larger than 1 if text encoder offload is enabled, as layer-wise offload plus prefetch is faster)
* `--sp-degree`: Sequence parallelism size (typically should match the number of GPUs)
* `--ulysses-degree`: The degree of DeepSpeed-Ulysses-style SP in USP
* `--ring-degree`: The degree of ring attention-style SP in USP

**AMD ROCm Notes**: Requires SGLang >= v0.5.8.

## 4. API Usage

For complete API documentation, please refer to the [official API usage guide](../../../docs/sglang-diffusion/api/openai_api).

### 4.1 Generate an Image

```python Example theme={null}
import base64
from openai import OpenAI

client = OpenAI(api_key="EMPTY", base_url="http://localhost:30000/v1")

response = client.images.generate(
    model="Qwen/Qwen-Image",
    prompt="A logo With Bold Large text: SGL Diffusion",
    n=1,
    response_format="b64_json",
)

# Save the generated image
image_bytes = base64.b64decode(response.data[0].b64_json)
with open("output.png", "wb") as f:
    f.write(image_bytes)
```

### 4.2 Advanced Usage

#### 4.2.1 Cache-DiT Acceleration

SGLang integrates [Cache-DiT](https://github.com/vipshop/cache-dit), a caching acceleration engine for Diffusion Transformers (DiT), to achieve up to 7.4x inference speedup with minimal quality loss. You can set `SGLANG_CACHE_DIT_ENABLED=True` to enable it. For more details, please refer to the SGLang Cache-DiT [documentation](../../../docs/sglang-diffusion/cache_dit).

**Basic Usage**

```bash Command theme={null}
SGLANG_CACHE_DIT_ENABLED=true sglang serve --model-path Qwen/Qwen-Image
```

**Advanced Usage**

* DBCache Parameters: DBCache controls block-level caching behavior:

<table style={{width: "100%", borderCollapse: "collapse", tableLayout: "fixed"}}>
  <colgroup>
    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />
  </colgroup>

  <thead>
    <tr style={{borderBottom: "2px solid #d55816"}}>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.02)"}}>Parameter</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.05)"}}>Env Variable</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.02)"}}>Default</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.05)"}}>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>Fn</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_FN`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>1</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Number of first blocks to always compute</td>
    </tr>

    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>Bn</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_BN`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>0</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Number of last blocks to always compute</td>
    </tr>

    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>W</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_WARMUP`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>4</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Warmup steps before caching starts</td>
    </tr>

    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>R</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_RDT`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>0.24</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Residual difference threshold</td>
    </tr>

    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>MC</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_MC`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>3</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Maximum continuous cached steps</td>
    </tr>
  </tbody>
</table>

* TaylorSeer Configuration: TaylorSeer improves caching accuracy using Taylor expansion:

<table style={{width: "100%", borderCollapse: "collapse", tableLayout: "fixed"}}>
  <colgroup>
    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />

    <col style={{width: "25.0%"}} />
  </colgroup>

  <thead>
    <tr style={{borderBottom: "2px solid #d55816"}}>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.02)"}}>Parameter</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.05)"}}>Env Variable</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.02)"}}>Default</th>
      <th style={{textAlign: "left", padding: "10px 12px", fontWeight: 700, whiteSpace: "nowrap", backgroundColor: "rgba(255,255,255,0.05)"}}>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>Enable</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_TAYLORSEER`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>false</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Enable TaylorSeer calibrator</td>
    </tr>

    <tr>
      <td style={{padding: "9px 12px", fontWeight: 500, backgroundColor: "rgba(255,255,255,0.02)"}}>Order</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>`SGLANG_CACHE_DIT_TS_ORDER`</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.02)"}}>1</td>
      <td style={{padding: "9px 12px", backgroundColor: "rgba(255,255,255,0.05)"}}>Taylor expansion order (1 or 2)</td>
    </tr>
  </tbody>
</table>

Combined Configuration Example:

```bash Command theme={null}
SGLANG_CACHE_DIT_ENABLED=true \
SGLANG_CACHE_DIT_FN=2 \
SGLANG_CACHE_DIT_BN=1 \
SGLANG_CACHE_DIT_WARMUP=4 \
SGLANG_CACHE_DIT_RDT=0.4 \
SGLANG_CACHE_DIT_MC=4 \
SGLANG_CACHE_DIT_TAYLORSEER=true \
SGLANG_CACHE_DIT_TS_ORDER=2 \
sglang serve --model-path Qwen/Qwen-Image
```

#### 4.2.2 CPU Offload

* `--dit-cpu-offload`: Use CPU offload for DiT inference. Enable if run out of memory.
* `--text-encoder-cpu-offload`: Use CPU offload for text encoder inference.
* `--vae-cpu-offload`: Use CPU offload for VAE.
* `--pin-cpu-memory`: Pin memory for CPU offload. Only added as a temp workaround if it throws "CUDA error: invalid argument".

#### 4.2.3 Known LoRA examples

Use `--lora-path` at startup or the [LoRA management API](/docs/sglang-diffusion/api/openai_api#lora-management) to load an adapter. Known Qwen-Image examples include:

* [`lightx2v/Qwen-Image-Lightning`](https://huggingface.co/lightx2v/Qwen-Image-Lightning)
* [`flymy-ai/qwen-image-realism-lora`](https://huggingface.co/flymy-ai/qwen-image-realism-lora)
* [`prithivMLmods/Qwen-Image-HeadshotX`](https://huggingface.co/prithivMLmods/Qwen-Image-HeadshotX)
* [`starsfriday/Qwen-Image-EVA-LoRA`](https://huggingface.co/starsfriday/Qwen-Image-EVA-LoRA)

## 5. Benchmark

Test Environment:

* Hardware: AMD Instinct MI300X GPU (1x)
* Model: Qwen/Qwen-Image
* Docker Image: lmsysorg/sglang:v0.5.8-rocm700-mi30x
* sglang diffusion version: 0.5.8

### 5.1 Speedup Benchmark

#### 5.1.1 Generate an image

<Tabs>
  <Tab title="AMD MI300X">
    **Server Command**:

    ```shell Command theme={null}
    sglang serve --model-path Qwen/Qwen-Image \
        --ulysses-degree=1 --ring-degree=1 --port 30000
    ```

    **Benchmark Command**:

    ```shell Command theme={null}
    python3 -m sglang.multimodal_gen.benchmarks.bench_serving \
        --dataset vbench --task text-to-image --num-prompts 1 --max-concurrency 1
    ```

    **Result**:

    ```text Output theme={null}
    ================= Serving Benchmark Result =================
    Task:                                    text-to-image
    Model:                                   Qwen/Qwen-Image
    Dataset:                                 vbench
    --------------------------------------------------
    Benchmark duration (s):                  29.04
    Request rate:                            inf
    Max request concurrency:                 1
    Successful requests:                     1/1
    --------------------------------------------------
    Request throughput (req/s):              0.03
    Latency Mean (s):                        29.0378
    Latency Median (s):                      29.0378
    Latency P99 (s):                         29.0378
    --------------------------------------------------
    Peak Memory Max (MB):                    48018.83
    Peak Memory Mean (MB):                   48018.83
    Peak Memory Median (MB):                 48018.83
    ============================================================
    ```
  </Tab>

  <Tab title="Ascend A3 Series">
    **Server Command**:

    ```shell Command theme={null}
    #One A3 Series card has 2 npu chips
    sglang serve --tp-size 2 --sp-degree 1 --model-path Qwen/Qwen-Image --num-gpus 2
    ```

    **Benchmark Command**:

    ```shell Command theme={null}
    python -m sglang.multimodal_gen.benchmarks.bench_serving --dataset vbench --task text-to-image --num-prompts 1 --max-concurrency 1
    ```

    **Result**:

    ```text Output theme={null}
    ================= Serving Benchmark Result =================
    Task:                                         text-to-image
    Model:                                        Qwen/Qwen-Image
    Dataset:                                      vbench
    --------------------------------------------------
    Benchmark duration (s):                       36.26
    Request rate:                                 inf
    Max request concurrency:                      1
    Successful requests:                          1/1
    Completed outputs:                            1
    Outputs per prompt:                           1
    --------------------------------------------------
    Request throughput (req/s):                   0.03
    Output throughput (outputs/s):                0.03
    Latency Mean (s):                             36.26
    Latency Median (s):                           36.26
    Latency P90 (s):                              36.26
    Latency P95 (s):                              36.26
    Latency P99 (s):                              36.26
    --------------------------------------------------
    Peak Memory Max (MB):                         36984.00
    Peak Memory Mean (MB):                        36984.00
    Peak Memory Median (MB):                      36984.00
    ------------------------------------------------------------
    ```
  </Tab>
</Tabs>

#### 5.1.2 Generate images with high concurrency

<Tabs>
  <Tab title="AMD MI300X">
    **Benchmark Command**:

    ```shell Command theme={null}
    python3 -m sglang.multimodal_gen.benchmarks.bench_serving \
        --dataset vbench --task text-to-image --num-prompts 20 --max-concurrency 20 --port 30000
    ```

    **Result**:

    ```text Output theme={null}
    ================= Serving Benchmark Result =================
    Task:                                    text-to-image
    Model:                                   Qwen/Qwen-Image
    Dataset:                                 vbench
    --------------------------------------------------
    Benchmark duration (s):                  300.79
    Request rate:                            inf
    Max request concurrency:                 20
    Successful requests:                     14/20
    --------------------------------------------------
    Request throughput (req/s):              0.05
    Latency Mean (s):                        154.5368
    Latency Median (s):                      154.8363
    Latency P99 (s):                         285.4603
    --------------------------------------------------
    Peak Memory Max (MB):                    48030.31
    Peak Memory Mean (MB):                   48030.30
    Peak Memory Median (MB):                 48030.29
    ============================================================
    ```
  </Tab>

  <Tab title="Ascend A3 Series">
    **Benchmark Command**:

    ```shell Command theme={null}
    python -m sglang.multimodal_gen.benchmarks.bench_serving --dataset vbench --task text-to-image --num-prompts 20 --max-concurrency 20
    ```

    **Result**:

    ```text Output theme={null}
    ================= Serving Benchmark Result =================
    Task:                                         text-to-image
    Model:                                        Qwen/Qwen-Image
    Dataset:                                      vbench
    --------------------------------------------------
    Benchmark duration (s):                       300.81
    Request rate:                                 inf
    Max request concurrency:                      20
    Successful requests:                          8/20
    Completed outputs:                            8
    Outputs per prompt:                           1
    --------------------------------------------------
    Request throughput (req/s):                   0.03
    Output throughput (outputs/s):                0.03
    Latency Mean (s):                             166.61
    Latency Median (s):                           167.02
    Latency P90 (s):                              270.80
    Latency P95 (s):                              283.48
    Latency P99 (s):                              293.64
    --------------------------------------------------
    Peak Memory Max (MB):                         36984.00
    Peak Memory Mean (MB):                        36984.00
    Peak Memory Median (MB):                      36984.00
    ------------------------------------------------------------
    ```
  </Tab>
</Tabs>
