Running Qwen-Image-2.1 on Mac: MPS Deployment, Directory Management, and Common Errors
Based on a deployment record on Apple Silicon, this guide organizes three routes—Diffusers + MPS, ComfyUI, and GGUF—provides isolated environment setup, model download, text-to-image and editing examples, and records issues such as missing torchvision, download progress, and memory pressure.
Sign into save this entry.
When trying Qwen-Image-2.1 on an Apple Silicon Mac, you can start with Diffusers + PyTorch MPS, then choose ComfyUI or GGUF depending on whether you need a graphical workflow or are constrained by memory. This article organizes a Mac deployment conversation into a standalone guide, preserving directory management, download, and troubleshooting experience, and corrects examples according to project documentation consulted on October 9, 2026.
The approach in the original conversation targeted an M4 Max with 64GB unified memory, and the last run log stopped at processor loading missing torchvision. Therefore, this provides deployment paths and troubleshooting records, and does not claim to have completed end-to-end generation, measured minimum configuration, or generation speed. The following examples were also not re-executed with large model inference when organizing the article.
1. How to choose among the three run routes
| Route | Suitable scenarios | Trade-offs to understand |
|---|---|---|
| Diffusers + MPS | Debugging in Python, maintaining scripts, integrating into your own programs | Direct interface; environment and dependencies need to be managed by yourself |
| ComfyUI + MPS | Using node workflows, combining reference images and editing steps | Graphical interface is convenient; model file layout and node versions need to match |
| stable-diffusion.cpp + GGUF + Metal | Researching quantization, command-line deployment, and lower memory usage | Need to prepare the generation model, text encoder, and VAE simultaneously, and verify backend support |
Qwen project provides entry points for Diffusers and ComfyUI; QwenImage21Pipeline handles text-to-image and reference image editing in the same pipeline. Qwen official project, Diffusers pipeline documentation.
ComfyUI's macOS desktop version targets Apple Silicon. The GGUF route can refer to the project maintainer's dedicated documentation, but smaller files do not necessarily mean faster generation; you still need to compare on your own machine. ComfyUI macOS installation, stable-diffusion.cpp Qwen-Image-2.1 documentation.
MLX is another route for runtime and model implementation; you cannot simply replace mps with mlx in Python examples to migrate. If considering it, first confirm the specific implementation supports Qwen-Image-2.1, the weight formats used, and the editing features needed.
2. Why you can't estimate configuration based on "7B" alone
The official 7B refers to the visual generation component; the entire pipeline also includes the Qwen3-VL condition encoder and VAE. Official model card.
This local download directory contains seven Safetensors weight files totaling approximately 33.12GB, about 30.84GiB:
| Component | Local weight files total, decimal approximation |
|---|---|
| Transformer | 14.23GB |
| Text/visual condition encoder | 17.53GB |
| VAE | 1.35GB |
File size only indicates the weight size on disk. Inference must also accommodate intermediate tensors, attention computation, output dimensions, and memory usage by the system and other applications; it does not equal peak unified memory requirements.
For the 64GB machine discussed here, BF16, single output, 1024×1024 is a reasonable starting point, not the official minimum configuration. For 32GB or less, you should first evaluate quantization or component offloading; do not treat a Q4 generation model of only a few GB as the entire system's footprint.
On first run, observe memory pressure and swap space in Activity Monitor. If there is heavy swap usage, first reduce resolution, close other high-memory applications, keep single-image generation, then evaluate optimizations supported by the current backend. Diffusers' MPS guide discusses memory pressure and slowdowns caused by swap; its attention slicing example mainly centers on Stable Diffusion, cannot treat "64GB" as a stable boundary for Qwen, and cannot guarantee the same switch works across all pipelines. MPS optimization notes.
3. Keep environment, models, and outputs in one directory
A valuable point in the original conversation is to keep all files centralized in one root directory. This not only eases maintenance but also preserves the large models when rebuilding the Python environment.
The minimal example in this article uses the following structure; .venv, models, cache, and outputs are created in subsequent steps:
qwen-image-2.1-mac/
├── .venv/
├── cache/
│ ├── huggingface/
│ ├── torch/
│ └── xdg/
├── inputs/
├── models/Qwen-Image-2.1/
├── outputs/
└── src/
├── common.py
├── download_model.py
└── run.py
In the terminal, create directories and set up an isolated environment. The example chooses Python 3.12 to specify the interpreter version; it does not mean other versions are unusable. If you already have a usable native arm64 Python 3.12, you can skip the Homebrew installation.
brew install python@3.12
mkdir -p "$HOME/models/qwen-image-2.1-mac"
cd "$HOME/models/qwen-image-2.1-mac"
mkdir -p src inputs outputs models cache
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip setuptools wheel
python -m pip install -U 'torch>=2.4.0' torchvision \
'transformers>=5.17' accelerate pillow huggingface_hub \
safetensors sentencepiece
python -m pip install -U 'git+https://github.com/huggingface/diffusers.git'
python -m pip check
Qwen's installation example gives the above Torch/Transformers minimum versions and the method to install Diffusers from source; this article adds torchvision, which was exposed by the later error. Version minimums only indicate installation constraints, not a verified set of complete locked versions. Qwen installation instructions.
torch and torchvision must use mutually compatible versions; if installation fails, check the official correspondence table. For long-term maintenance, after successful generation, save the result of python -m pip freeze and record the Diffusers Git commit and model revision to avoid one upgrade changing all dependencies simultaneously. Torchvision version correspondence table.
First check the interpreter and backend:
python - <<'PY'
import platform
import sys
import torch
import torchvision
from diffusers import QwenImage21Pipeline
print("Python:", sys.version.split()[0])
print("Architecture:", platform.machine())
print("Torch:", torch.__version__)
print("Torchvision:", torchvision.__version__)
print("MPS built:", torch.backends.mps.is_built())
print("MPS available:", torch.backends.mps.is_available())
PY
The goal is a native arm64 environment with MPS available as True. This step verifies dependency import and GPU backend availability, but still requires actual loading, generation, and saving of images to complete end-to-end verification.
4. Separate download and generation to avoid repeatedly pulling models
Save the following code as src/common.py. It sets the project's internal cache locations before importing Hugging Face, Torch and other libraries:
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
MODEL_DIR = ROOT / "models" / "Qwen-Image-2.1"
OUTPUT_DIR = ROOT / "outputs"
for variable, folder in {
"HF_HOME": "huggingface",
"TORCH_HOME": "torch",
"XDG_CACHE_HOME": "xdg",
}.items():
location = ROOT / "cache" / folder
location.mkdir(parents=True, exist_ok=True)
os.environ[variable] = str(location)
Then save src/download_model.py:
from common import MODEL_DIR
from huggingface_hub import snapshot_download
MODEL_DIR.mkdir(parents=True, exist_ok=True)
snapshot_download(
repo_id="Qwen/Qwen-Image-2.1",
local_dir=str(MODEL_DIR),
)
print("Model directory:", MODEL_DIR)
Run:
source .venv/bin/activate
python src/download_model.py
snapshot_download supports reusing already downloaded content. When local_dir is specified, the Hub also creates .cache/huggingface metadata under the model directory for subsequent checks; it is not the same as the cache/ directory at the root. Repeated execution with the same revision and directory usually reuses existing files; if the upstream revision changes, it may also download updated files. Hub download and local directory instructions.
If the terminal leaves a lower percentage progress line, do not judge the download as failed based only on that line. First see whether the command terminated normally and whether there is a final error; if unsure, rerun the same download command. Having only model_index.json or a check script showing "Model downloaded: YES" also cannot alone prove all shards are complete.
5. Minimal text-to-image and image editing examples
Save as src/run.py. It only reads the downloaded local model and starts with 1024×1024, single output by default; the CPU random number generator is used to provide a fixed seed, and the pipeline then places the required tensors on MPS.
import argparse
from datetime import datetime
from common import MODEL_DIR, OUTPUT_DIR
import torch
from PIL import Image
from diffusers import QwenImage21Pipeline
parser = argparse.ArgumentParser()
parser.add_argument("--prompt", required=True)
parser.add_argument("--image")
parser.add_argument("--size", type=int, default=1024)
parser.add_argument("--steps", type=int, default=40)
parser.add_argument("--seed", type=int, default=42)
args = parser.parse_args()
if args.size <= 0 or args.size % 32 or args.steps <= 0:
parser.error("size must be a positive multiple of 32; steps must be positive")
if not torch.backends.mps.is_available():
raise RuntimeError("MPS is unavailable; check native Python and PyTorch")
pipeline = QwenImage21Pipeline.from_pretrained(
str(MODEL_DIR),
dtype=torch.bfloat16,
local_files_only=True,
).to("mps")
options = {
"prompt": args.prompt,
"num_inference_steps": args.steps,
"generator": torch.Generator("cpu").manual_seed(args.seed),
}
if args.image:
with Image.open(args.image) as source:
options["image"] = source.convert("RGBA")
options["output_resolution"] = args.size
else:
options["width"] = args.size
options["height"] = args.size
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
result = pipeline(**options).images[0]
name = datetime.now().strftime("qwen-%Y%m%d-%H%M%S-%f.png")
destination = OUTPUT_DIR / name
result.save(destination)
print("Saved:", destination)
Text-to-image:
python src/run.py \
--prompt '一张复古电脑放在木桌上的照片,窗边自然光,清晰细节' \
--size 1024 --steps 40 --seed 42
Edit with reference image:
python src/run.py \
--image inputs/photo.png \
--prompt '保留主体的外观,把背景改成柔和的日落海边' \
--size 1024 --steps 40
The editing path uses image and output_resolution, letting the pipeline calculate dimensions based on the input aspect ratio; here size is the target area scale and does not promise output exactly at the original image pixel size. Save PNG and preserve input RGBA to avoid the example discarding transparency when reading. Fixed seed facilitates comparison in the same environment; it does not guarantee pixel-by-pixel consistency across versions or backends. Pipeline parameters and image preprocessing.
After confirming normal image saves, try --size 2048. The official model example uses 2048×2048, 40 steps; 1024 is the starting point chosen here for troubleshooting, and should be understood separately from the model's native 2K usage goal. Official generation example.
The above script covers only the minimal process and does not include batching, GUI, image quality validation, or automatic memory optimization. If continuing with the .command script package from the original conversation, you can keep the "install → download → check → generate/edit" entry division, making Finder double-click entries thin wrappers that call the same set of Python files.
6. The most useful error experience from this deployment
Missing torchvision after processor loaded to 80%
In the original record, weight shards had entered the loading process, then the following appeared:
Qwen3VLVideoProcessor requires the Torchvision library
This indicates the first thing to solve is the processor dependency import. Even if the current task only generates static images, the combined processor initialization may require video processing-related dependencies.
Install matching versions in the same virtual environment, then exit the original process and restart:
source .venv/bin/activate
python -m pip install -U torch torchvision
python -m pip check
python -c 'import torch, torchvision; print(torch.__version__, torchvision.__version__)'
Do not delete the 33GB model first for this ImportError. Fixing the dependency can resolve the current error; whether other issues follow should be judged from new logs.
Deprecation warning for torch_dtype
The conversation also showed a deprecation warning for torch_dtype, which was not the direct cause of that ImportError. This article uses dtype=torch.bfloat16 according to the current Diffusers pipeline documentation; when maintaining old scripts, update the parameter name after confirming the version in use supports it.
python3 automatically selected 3.14
The original script preferred several explicit versions and finally fell back to python3, actually selecting Python 3.14. When troubleshooting, first print sys.executable, Python version, and architecture; do not assume the command name represents a fixed version.
If you need to use Python 3.12, exit the virtual environment, rename the old .venv to keep it, and recreate; keep models/, inputs/, and outputs/. There is no need to redownload the entire model set because of the interpreter change.
MPS available but image editing results are abnormal
Text-to-image success cannot replace editing acceptance: reference image editing also goes through VAE encoding. In ComfyUI's issue report #16433, the reporter's specific MPS environment had Qwen-Image-2.1 VAE encoding anomalies, and reported that CPU VAE could bypass the issue; patch discussions have since occurred.
If you encounter reference image becoming noise, color cast, or structural damage in a similar environment, you can use python main.py --cpu-vae for a ComfyUI control investigation, then check whether the actual version includes the relevant fix. This is a troubleshooting method for the report, not indicating all Macs necessarily have it, nor a startup parameter that can be directly applied to Diffusers.
7. What to preserve during maintenance
- When fixing dependencies, keep the model directory; when rebuilding the environment, handle
.venvseparately. - When clearing cache, confirm the target directory; the download metadata inside the model directory serves its own purpose, so do not treat the entire root directory as cache.
- Acceptance checks should be done separately: dependency import, MPS availability, full loading, text-to-image saving, reference image editing, and result appearance.
- Record actual Python, Torch, Torchvision, Transformers, Diffusers, and model revision, and keep complete error logs.
- Avoid claiming full validation or speed conclusions based only on download percentage,
MPS=True, or a single output file.
8. Model license and scope of applicability
Qwen-Image-2.1 currently uses the Qwen Research License Agreement, not Apache 2.0. The agreement limits non-commercial use to research or evaluation; commercial use requires separate permission. Before connecting to paid applications or services, read the specific terms. Model license original text.
This article organizes local research and environment maintenance methods, and does not distribute model weights, original conversation attachments, or inference services. Interfaces, dependencies, and compatibility issues will continue to change; when actually installing, verify the corresponding version's project documentation.
READER CORRESPONDENCE
Comments (0)
Sign in to comment or reply. Submissions appear after moderation.
Sign into comment or reply.
No comments yet.