HuggingFace の diffusers ライブラリに含まれる QwenImageEditPlusPipeline を使って 512×512 の画像を編集しようとすると、出力画像が不自然にズームインされたり画角がズレる現象が起きます。この記事ではその原因とコード修正方法を解説します。


🔍 現象

以下のようなコードで 512×512 の入力画像を処理すると、生成結果が元画像よりも「寄り」になってしまいます。

inputs = {
    "image": image,          # 512×512 の画像
    "prompt": prompt,
    "width": 512,
    "height": 512,
    ...
}
pipe(**inputs)

回避策として width/height を 1.75〜2 倍(例:896px や 1024px)にすると元の画角に近くなることが知られていますが、これは根本的な解決ではありません。


🐛 原因:VAE_IMAGE_SIZE のハードコード

原因はソースコード内にある 1行の定数 です。

ファイル:diffusers/src/diffusers/pipelines/qwenimage/pipeline_qwenimage_edit_plus.py

vae_width, vae_height = calculate_dimensions(VAE_IMAGE_SIZE, image_width / image_height)
  # ← ここが問題

この定数により、width=512, height=512 を指定しても VAEには常に 1024×1024 にリサイズされた画像が渡されます

内部でこのような処理が行われています。

# __call__ 内の処理(抜粋)
vae_width, vae_height = calculate_dimensions(
    VAE_IMAGE_SIZE,            # 常に 1024×1024 相当
    image_width / image_height
)
vae_images.append(
    self.image_processor.preprocess(img, vae_height, vae_width).unsqueeze(2)
)

結果として、以下のような不一致が生じます。

入力画像    →  VAE処理      →  latent
512×512    →  1024×1024   →  128×128(VAEの出力)

ノイズlatent(width/height=512 より計算)
512×512 → 64×64

→ mismatch → ズームイン/画角ズレ

この問題は GitHub でも報告・議論されており(PR #12453)、執筆時点でまだ main ブランチにマージされていません。


✅ 修正方法

__call__ 内の該当箇所を以下のように変更します。

変更前

vae_width, vae_height = calculate_dimensions(
    VAE_IMAGE_SIZE,
    image_width / image_height
)

変更後

vae_width, vae_height = calculate_dimensions(
    height * width,            # ← 指定した解像度を使う
    image_width / image_height
)

これにより、width=512, height=512 を指定した場合、VAE も 512×512 で処理されるようになり、latent サイズの不一致が解消されます。

さらにシンプルな方法

縦横比を完全に固定したい場合は calculate_dimensions を省略して直接代入することもできます。

vae_width, vae_height = width, height

ただし calculate_dimensions は 32 の倍数に丸めてくれるため、基本的にはこちらを使うのが安全です。


🔧 コードを直接書き換えたくない場合の回避策

ソースを編集せずに実行時に定数を上書きする方法もあります。

import diffusers.pipelines.qwenimage.pipeline_qwenimage_edit_plus as qwen_mod

qwen_mod.VAE_IMAGE_SIZE = height * width  # 実行前に上書き

pipe(**inputs)

📌 まとめ

項目 内容
問題のファイル pipeline_qwenimage_edit_plus.py
問題の箇所 VAE_IMAGE_SIZE = 1024 * 1024(定数)
症状 512px 指定時に出力がズームインされる
修正方法 calculate_dimensions(height * width, ...) に変更
マージ状況 PR #12453(執筆時点で未マージ)

1.75〜2 倍にすると画角が近くなる理由もこれで説明できます。VAE が 1024px で処理する → latent が 2 倍のサイズ → 元のサイズの 2 倍で渡せばマッチする、という単純な比率の問題でした。


参考:GitHub PR #12453 – Fix QwenImageEditPlusPipeline not using the passed in width/height for the VAE