Qwen_Image-2.1-MXFP4

Built with Qwen. This portable package contains the balanced MXFP4 weights converted by EliovpAI from Qwen-Image-2.1. The weight tensors are unchanged from our previously prepared balanced checkpoint. It supports text-to-image generation, single-image editing and transparent RGBA output through the supplied Python API and command line launcher.

The tensor payload is 8.674 GiB. All components remain resident on one GPU. The runtime reconstructs each packed weight in BF16 for the original framework operation. Activations remain BF16. This is weight storage compression, not native FP4 matrix multiplication. There is no custom native library or model compiler to build or load. Quark is not required for inference.

The supplied loader is necessary: this custom packed checkpoint cannot be loaded with an unmodified DiffusionPipeline.from_pretrained call.

Compatibility and tested scope

The intended target is an AMD GPU supported by the installed ROCm PyTorch stack, with BF16 support and enough free VRAM for the complete request. The loader does not impose an architecture whitelist. GPU family alone does not establish that a particular driver, wheel, operating system or memory capacity will work.

Hardware qualification for this portable package uses one MI355X, architecture gfx950, with Torch 2.10.0+rocm7.1 and HIP 7.1.25424. Other GPUs are not qualified by that result. Consult AMD's ROCm compatibility documentation for the prerequisites of the chosen stack.

Request profile Supplied limits
Text to image 1024 × 1024 or 2048 × 2048
RGBA generation 1024 × 1024 or 2048 × 2048
Editing One input image, at most 4,194,304 input pixels; 1024 × 1024 output
Sampling Batch one, 40 steps, true guidance 1.0, prefix KV reuse enabled
Prompt 1 to 512 characters
Concurrency One active request per worker and one cooperating worker per selected GPU
Graphs Eager complete pipeline; whole-pipeline graph capture is unsupported

The API rejects unsupported sizes, batches, guidance and step counts before GPU execution. This bounded profile does not establish video generation, arbitrary aspect ratios, multi-image editing or multiple simultaneous workers.

Exact model and arithmetic

Original model revision: 790c92633540aa0cb11d9abf19eb46d861714758. Diffusers revision: 7263f3317f6b392d62f41e9d75ed9d7e21fc5a5c. Checkpoint identities, including the tokenizer, scheduler and component configs, are pinned in checkpoint.lock.json. Startup verifies their SHA-256 hashes. result.json describes the tensor layout and lists every converted layer.

Component Original BF16 inference payload Balanced payload
Diffusion transformer 13.253 GiB 3.706 GiB
Text and vision encoder 16.330 GiB 4.339 GiB
VAE 0.629 GiB 0.629 GiB
Total 30.212 GiB 8.674 GiB

The balanced checkpoint packs 224 primary diffusion matrices and 372 text/vision matrices, embedding tables and patch-convolution weights. Small diffusion input/output/conditioning matrices, the VAE, normalization parameters and biases remain BF16. The word MXFP4 does not mean that every tensor has been converted to four bits. This package contains the balanced profile only.

Storage uses low-nibble-first E2M1 values with one E8M0 scale per 32 input columns. Convolution weights are flattened by output channel and zero-padded to a multiple of 32 columns; the decoder crops that padding and restores the original shape. Embedding lookup reconstructs only requested rows. Loading streams tensors to avoid a second complete expanded model in host memory.

The existing conversion used Quark weight-only rounding, without activation calibration, GPTQ, learned correction or retraining. Preparing this portable consumer did not requantize, repack or alter any stored weight tensor. The archived conversion reproduction checked all 1,881 stored tensors bit for bit. Descriptive format labels in 23 shard headers were normalized for this standalone package. All tensor names, shapes, dtypes, offsets and data bytes were verified unchanged. measurements/metadata-verification.json maps the original benchmark manifest to the final checkpoint manifest; the final checkpoint also passed a fresh CLI run.

Install and run

Use Python 3.12 in an isolated environment. Start with a ROCm PyTorch stack that supports your GPU. The full tested dependency closures are recorded in requirements-mi355.lock.txt and environment.lock.json. The tested MI355X setup can be reproduced as follows:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install torch==2.10.0+rocm7.1 torchvision==0.25.0+rocm7.1 \
  --index-url https://download.pytorch.org/whl/rocm7.1
python -m pip install -r requirements-mi355.lock.txt \
  --extra-index-url https://download.pytorch.org/whl/rocm7.1
python -m pip check

Use the pinned Diffusers commit, not an older distribution that lacks QwenImage21Pipeline. requirements.txt pins the primary image dependencies for an existing compatible stack; use the full selected lock for exact reproduction. The adapter uses eager operations and disables compilation. Auxiliary packages listed by the upstream Torch wheel remain subject to that wheel's requirements.

From the unpacked package directory:

python tools/verify_package.py --package .
./launch.sh --model-dir . generate \
  --prompt 'A neon shop sign that reads "QWEN IMAGE 2.1", rainy night, reflections on wet pavement' \
  --size 2048 --seed 42 --output ../outputs/neon.png

./launch.sh --model-dir . generate \
  --mode rgba --prompt 'A cute cartoon dragon sticker.' \
  --size 2048 --seed 52 --output ../outputs/dragon.png

./launch.sh --model-dir . generate \
  --mode edit --image ../inputs/teapot.png \
  --prompt 'Change the blue teapot to bright red. Keep the table and composition.' \
  --size 1024 --seed 53 --output ../outputs/red-teapot.png

The package root contains result.json, checkpoint.lock.json, text_encoder/, transformer/, vae/, processor/ and scheduler/. Set --model-dir to that root. QWEN_IMAGE21_PYTHON may select a different Python executable for the shell launcher. Existing image files are not overwritten. Each generated PNG has a JSON sidecar recording the exact settings, timing, memory and checkpoint identity. Keep outputs outside the immutable release directory when verifying its allowlist.

RGBA mode adds the upstream transparency prompt wording. Ordinary prompts also return RGBA PNGs but can have nearly opaque alpha. Keep PNG format to retain transparency; an RGBA file mode alone does not prove a transparent background.

Examples: 2048 generation, 2048 RGBA, edit input, edited image.

Local API

./launch.sh --model-dir . serve --port 8192
curl http://127.0.0.1:8192/v1/images/generations \
  -H 'Content-Type: application/json' \
  -d '{"model":"qwen-image-2.1-mxfp4","prompt":"A blue ceramic teapot on a wooden table","size":"2048x2048","seed":42,"n":1}'

GET /health reports readiness, checkpoint identity, load time and hardware. GET /v1/models lists task limits. Generation returns a base64 PNG in data[0].b64_json, plus complete-request measurements in metrics. For POST /v1/images/edits, send JSON with prompt, one base64-encoded image in image_b64, size: "1024x1024" and seed. This endpoint uses JSON rather than multipart form data. It does not fetch URLs or open client-supplied file paths. The body limit is 32 MiB and a concurrent GPU request receives HTTP 409.

Python usage:

from qwen_image21.runtime import ImageEngine
engine = ImageEngine('/path/to/checkpoint')
image, png, metrics = engine.generate('A blue ceramic teapot', width=1024, height=1024)
image.save('/path/to/teapot.png')

Memory and latency

All model components stay on the GPU, without CPU model offload or VAE tiling. Single-frame VAE calls discard unused temporal caches and use the verified convolution configuration MIOPEN_FIND_MODE=FAST, MIOPEN_DEBUG_CONV_GEMM=0. Condition-image prefix caches are released before final decoding and between requests. Each operation's expanded weight is temporary.

The optional global --memory-budget-gib flag limits the framework allocator. It does not reserve VRAM, cover every library allocation, or guarantee that a request fits. There is no universal 30 GiB admission rule. Required memory depends on the image profile, runtime algorithms, allocator history and other GPU users. A small request following a large one may retain the larger allocator reservation.

MI355X, the exact locked balanced checkpoint, batch one, 40 steps and guidance 1.0:

Request Full HTTP request Sampled device peak
2048 text to image, first 22.83 s 32.31 GiB
2048 text to image, warm repeat 1 21.44 s 32.05 GiB
2048 text to image, warm repeat 2 21.58 s 32.05 GiB
1024 text to image after the large requests 6.19 s 32.05 GiB
2048 RGBA 21.18 s 32.41 GiB
1024 RGBA after the large request 6.01 s 32.41 GiB
1024 single-image edit 7.17 s 32.44 GiB

A separate fresh-process 1024 text-to-image CLI request completed through PNG in 7.57 seconds at 18.97 GiB sampled device peak and 16.37 GiB framework allocation. Its record is measurements/mi355-fresh1024.json. This establishes a tested small profile, not a universal memory guarantee for every prompt and device.

No memory cap was applied. These are full-suite device peaks with allocator history, not separate minimum-VRAM estimates for the smaller profiles. Startup to API readiness took 11.02 seconds, including file verification. The exact per-request allocation, reservation, startup and identity records are in measurements/mi355-api.json.

Times include the full 40-step request and PNG encoding; API measurements also include local HTTP/base64 transfer. Startup, including verification and loading, is reported separately. First requests use existing filesystem and kernel caches; these are process-cold measurements rather than clean-install measurements. Whole-device usage is sampled every 20 ms and can miss brief transients. Framework allocated and reserved high-water marks are also recorded. Device peaks are observations, not guaranteed minimum capacity or performance promises.

Quality and reproducibility

The retained eight-prompt quality screen uses 2048² images, 40 steps, guidance 1.0 and one fixed seed per prompt. It covers typography, portrait, product, wildlife, spatial relations, illustration, landscape and poster generation. BF16 and balanced outputs, settings and hashes are included in evaluation/images/.

Metric BF16 Balanced MXFP4
Mean CLIPScore 0.90313 0.86839
Mean LPIPS versus paired BF16 0 0.19177

CLIPScore uses CLIP ViT-B/32, the A photo depicts prefix and 2.5 × max(cosine(image, text), 0) in float32 on CPU. LPIPS uses AlexNet v0.1, RGB images resized to 512² with bicubic interpolation and inputs in [-1,1]. This metric resize does not alter the generated resolution. Model hashes are pinned in evaluation/metric-manifest.json.

Balanced mean CLIPScore is about 3.85% below BF16 in this small sample. These numbers describe a quality tradeoff, not unchanged quality, statistical equivalence or a human-preference guarantee. LPIPS also responds to composition changes. No FID/KID estimate is made from eight examples.

The new portable loader regenerated all eight archived balanced quality images byte for byte on MI355X. Running the pinned CPU evaluator on those new outputs reproduced every archived per-image score and the table above exactly. See measurements/mi355-quality-generation.json and measurements/mi355-quality.json.

The MI355X hardware suite passed all tasks. Its three identical 2048 prompts produced identical PNGs. A separate instrumented seven-request sequence verified bitwise-identical prompt embeddings and final denoising latents for A, A, RGBA, A, edit, A, A. The BF16 VAE can produce small pixel differences even on immediate repeats in this stack. Consequently the final PNG is not promised to be bitwise identical across every request order or hardware/software combination.

The API screen records those differences and requires RGBA mean absolute error at most 0.25 and maximum error at most 8 on the 0-255 scale for A-B-A. The separate isolation test requires exact conditioning and denoising tensors. These image limits are a repeatability check, not a general quality-equivalence threshold. The final API sequence had image MAE 0.0415 and maximum difference 3. See measurements/mi355-isolation.json for the final tensor-level results.

Reproduce validation with a fresh output directory:

python -m unittest discover -s tests -v
timeout --signal=TERM --kill-after=15s 900s python tools/validate_api.py \
  --model-dir . --output ../validation/api
python tools/check_isolation.py --model-dir . --output ../validation/isolation

# Regenerate the eight paired prompts through this exact loader.
timeout --signal=TERM --kill-after=15s 900s python tools/quality_generate.py \
  --model-dir . --output ../validation/balanced

# CPU metrics, kept separate from GPU timings.
python -m pip install -r requirements-evaluation.lock.txt \
  --extra-index-url https://download.pytorch.org/whl/rocm7.1
python tools/prepare_metrics.py --output ../metric-cache
python tools/evaluate.py --reference evaluation/images/bf16 \
  --candidate ../validation/balanced --clip-dir ../metric-cache/clip \
  --torch-hub-dir ../metric-cache/torch-hub --output ../validation/quality

The API harness verifies startup, rejected settings, repeated 2048 generation, RGBA at both sizes, editing, and A-B-A request isolation. Each process owns a cooperative GPU lock; QWEN_IMAGE21_GPU_LOCK can select a shared physical-device lock where multiple device-index mappings are used. The library accepts one checkpoint per engine. Restart the process to change checkpoints.

License and attribution

The unchanged upstream Qwen Research License is included in LICENSE, with the required attribution in NOTICE. Quantization does not replace that license. See THIRD_PARTY_NOTICES.md for adapter, framework and evaluation attribution. All model rights remain subject to the upstream agreement. No additional model-use permission is implied here.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for EliovpAI/Qwen_Image-2.1-MXFP4

Quantized
(58)
this model