CCCMKホールディングス TECH LABの Tech Blog

TECH LABのエンジニアが技術情報を発信しています

ブログタイトル

Qwen-Image-Edit-2509を試してみました。

こんにちは、CCCMKホールディングスAIエンジニアの三浦です。

秋の夕暮れ時が好きで、その時間に合わせてよく散歩をします。暗くなり人の顔が見えなくなって「あなたは誰ですか」とたずねる頃合いなので"黄昏(たそがれ)時"というんだよ、という話をふと思い出しました。

この前画像生成AIについて調べていたのですが、その際に"Qwen-Image"という Alibaba Cloudが開発した画像生成モデルについて知りました。このモデルは"text-to-image"(プロンプトで画像を生成する)タスクと"text-image-to-image"(入力画像をプロンプトで編集する)タスクに対応しており、Hugging Faceで公開されています。

huggingface.co

このQwen-Imageをベースにして画像編集機能が拡張された"Qwen-Image-Edit"というモデルの現時点の最新版"Qwen-Image-Edit‐2509"をdatabricksのA100環境で動かしてみたのですが想像以上に高性能でびっくりしました。Qwen-Imageは特に画像内における自然なテキストの描画能力が高いようで、英語と中国語に対応しているとモデルの説明に書かれていますが日本語でもある程度の性能が出ているように感じました。

今回databricksで利用できるA100GPU1台で2,000x1,125のサイズの画像の編集を実行できることを確認出来ました。この記事ではdatabricksでQwen-Image-Edit-2509を動かした際に作成したNotebookの具体的な内容の紹介と画像生成時に指定できるパラメータtrue_cfg_scaleの効果について調べたことをまとめてみたいと思います。

databricksのNotebookでQwen-Image-Edit-2509を動かしてみる

databricksのNotebookでQwen-Image-Edit-2509を動かした際の手順をご紹介します。使用したRuntime for Machine Learningのバージョンは"17.3 LTS"です。

まず最新版のdiffusersをGithubレポジトリから取得してインストールし、さらにtransformersの更新を行います。

%pip install git+https://github.com/huggingface/diffusers
%pip install transformers -U
dbutils.library.restartPython()

つぎにモデルをダウンロードします。Hugging Faceのモデルカードはこちらです。

huggingface.co

import os

from diffusers import QwenImageEditPlusPipeline
from PIL import Image
import torch

pipeline = QwenImageEditPlusPipeline.from_pretrained(
    "Qwen/Qwen-Image-Edit-2509", 
    torch_dtype=torch.bfloat16
)
print("pipeline loaded")

pipeline.to('cuda')
pipeline.set_progress_bar_config(disable=None)

これで準備は完了です。次のような画像を読み込み、""の文字色を赤色に変更してみます。

読み込ませる画像

与えるプロンプトは'Change the color of character"け" to red.'のようにしました。

image = Image.open("./images/example_image.png").convert("RGB")

# 元のサイズを保持
input_size = image.size

prompt = 'Change the color of character"け" to red.'

inputs = {
    "image": image,
    "prompt": prompt,
    "generator": torch.manual_seed(0),
    "true_cfg_scale": 6.0,
    "negative_prompt": " ",
    "num_inference_steps": 20,
}
with torch.inference_mode():
    output = pipeline(**inputs)
    output_image = output.images[0]

output_image = output_image.resize(input_size)

以下のような画像が生成されました。

"け"の文字だけ赤色に着色された

日本語の平仮名"け"を正しく認識し、指示通りの着色が出来ました。他にも背景を変える、といったことも出来ます。'Add the snow scene to behind all contents.'というプロンプトを与えると、以下のような画像が生成されました。

背景を雪景色に変更

文字が発光してますね。雰囲気のいい画像に編集されました。

ちなみに画像生成のパラメータにwidthheightを指定すると生成される画像サイズを変更することが出来るのですが、このパラメータを指定すると私の環境では生成される画像の質が落ちたりプロンプトに従わなくなるような動作が見られました。ですので先に掲載したコードでは生成画像をオリジナル画像のサイズにリサイズする処理を最後に実行するようにしています。

画像生成のパラメータtrue_cfg_scaleについて

画像生成時にtrue_cfg_scaleというパラメータを指定していますが、これはどれだけプロンプトの影響を画像に反映させるのかを制御する値です。

"CFG"は"Classifier-Free Diffusion Guidance"を指しており、これはDiffusion Modelの画像生成の過程の中にプロンプトの持つ意味を取り込ませるテクニックです。

CFGが提案されている論文を少し読んでみたのですが、仕組みとしては生成用のプロンプトとネガティブプロンプトごとにDiffusion Modelの推論を実行し、推論されたノイズの差分を求め全体のノイズに加算するようです。加算するノイズの差分に重みを掛けているのですがそれがtrue_cfg_scaleに該当します。

このようなアプローチであるため、true_cfg_scaleを指定する場合はネガティブプロンプトnegative_promptの指定も必要になります。特にネガティブプロンプトが必要ない場合には" "を指定するようにします。

先ほどの画像を例に、true_cfg_scaleを変動させた様子を見てみます。

'Change the color of character"け" to red.'の場合です。

  • true_cfg_scale=1.0

`true_cfg_scale=1.0`

  • true_cfg_scale=5.0

`true_cfg_scale=5.0`

true_cfg_scale=5.0の方がプロンプトの指示"文字色を赤くする"により強く従っているように感じます。一方true_cfg_scale=1.0の方が全体と調和がとれた着色がされた画像が生成されているように感じます。

'Add the snow scene to behind all contents.'の方も見てみます。こちらはもう少し幅広い範囲でtrue_cfg_scaleを動かしてみました。 (データサイズを抑えるため、画像のサイズを小さくしています。)

  • true_cfg_scale=1.0

`true_cfg_scale=1.0`

  • true_cfg_scale=5.0

`true_cfg_scale=5.0`

  • true_cfg_scale=30.0

`true_cfg_scale=30.0`

ここまで動かすとだいぶ生成される画像の雰囲気が変わるな・・・と思いました。まずtrue_cfg_scale=1.0だとすごくフォトリアルな画像が生成されました。true_cfg_scale=5.0が今回の中では一番好みです。きれいな要素と親しみやすい要素がちょうど良く入っている印象があるからです。true_cfg_scale=30.0は親しみやすい印象は強いのですが、画像の品質の面で低いように感じました。

最初の例だとtrue_cfg_scale=1.02つ目の例はtrue_cfg_scale=5.0が良いと感じました。なのでこのパラメータは決め打ちで使うというよりは扱う画像や出したい画像に応じて適宜調整する必要があると思います。

まとめ

Qwen-Image-Edit-2509を今回使ってみましたが、想像以上に高品質な画像が生成され、かつプロンプトにもかなり忠実にしたがってくれるように感じました。ただやはり日本語のテキストの扱いはうまくいかないケースも時々発生しました。こういった課題をたとえばLoRAといったテクニックで解決できるかも、今後調べていきたいと考えています。