0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EVO-X2でZ-Image-Turboやーる(Windows11、Python3.12)

0
Last updated at Posted at 2025-12-07

はじめに

EVO-X2でZ-Image-Turboを動かしてみました

開発環境

  • EVO-X2
  • Python 3.12
  • ComfyUI 0.3.75

導入

下記の記事を参考にEVO-X2にComfyUIをセットアップします。

フォルダ構成はこちらになります。

workspace/ # 作業用ディレクトリ
├── ComfyUI/ # ComfyUIのルートディレクトリ
│ ├── models/
│ │ ├── diffusion_models/
│ │ │ └── z-image-turbo-fp8-e4m3fn.safetensors
│ │ ├── clip/
│ │ │ └── qwen_3_4b.safetensors
│ │ └── vae/
│ │   └── ae.safetensors
│ └── ... # ComfyUIのその他のファイル
│
└── my-z-image/ # このプロジェクト
│ ├── standalone/
│ ├── z-image-turbo.py
│ └── results/
│
└── README.md

まず、作業用ディレクトリに移動し、ComfyUIをクローンします。

cd workspace
git clone https://github.com/comfyanonymous/ComfyUI

requirements.txtからtorch、torchaudio、torchvisionを削除します。

requirements.txt
comfyui-frontend-package==1.32.9
comfyui-workflow-templates==0.7.23
comfyui-embedded-docs==0.3.1
torchsde
numpy>=1.25.0
einops
transformers>=4.50.3
tokenizers>=0.13.3
sentencepiece
safetensors>=0.4.2
aiohttp>=3.11.8
yarl>=1.18.0
pyyaml
Pillow
scipy
tqdm
psutil
alembic
SQLAlchemy
av>=14.2.0

#non essential dependencies:
kornia>=0.7.1
spandrel
pydantic~=2.0
pydantic-settings~=2.0

必要なライブラリをインストールします。

pip install --index-url https://repo.amd.com/rocm/whl/gfx1151/ "rocm[libraries,devel]"
pip install --index-url https://repo.amd.com/rocm/whl/gfx1151/ --pre torch torchaudio torchvision
pip install -r requirements.txt
pip install git+https://github.com/huggingface/diffusers

以下のモデルを手動でダウンロードし、配置します。

プロジェクトフォルダ(my-z-image/standalone)に下記のPythonプログラムを作成します。

プログラムの作成は下記を参考にしています。

z-image-turbo.py
import os
import sys
import random
import time
import re
import uuid

import torch
import numpy as np
from PIL import Image

# ComfyUIのパスを設定(必要に応じて変更してください)
COMFYUI_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "ComfyUI"))

# ComfyUIをパスに追加
sys.path.insert(0, COMFYUI_PATH)

# ComfyUIのノードをインポート
from nodes import NODE_CLASS_MAPPINGS

# 結果の保存先ディレクトリ
SAVE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "results")
os.makedirs(SAVE_DIR, exist_ok=True)


def load_models():
    """モデルをロードする"""
    print("モデルをロード中...")
    
    UNETLoader = NODE_CLASS_MAPPINGS["UNETLoader"]()
    CLIPLoader = NODE_CLASS_MAPPINGS["CLIPLoader"]()
    VAELoader = NODE_CLASS_MAPPINGS["VAELoader"]()
    
    with torch.inference_mode():
        unet = UNETLoader.load_unet("z-image-turbo-fp8-e4m3fn.safetensors", "fp8_e4m3fn_fast")[0]
        clip = CLIPLoader.load_clip("qwen_3_4b.safetensors", type="lumina2")[0]
        vae = VAELoader.load_vae("ae.safetensors")[0]
    
    print("モデルのロード完了!")
    return unet, clip, vae


def get_save_path(prompt):
    """保存パスを生成"""
    safe_prompt = re.sub(r'[^a-zA-Z0-9_-]', '_', prompt)[:25]
    uid = uuid.uuid4().hex[:6]
    filename = f"{safe_prompt}_{uid}.png"
    path = os.path.join(SAVE_DIR, filename)
    return path


@torch.inference_mode()
def generate(unet, clip, vae, input_params):
    """画像を生成"""
    CLIPTextEncode = NODE_CLASS_MAPPINGS["CLIPTextEncode"]()
    KSampler = NODE_CLASS_MAPPINGS["KSampler"]()
    VAEDecode = NODE_CLASS_MAPPINGS["VAEDecode"]()
    EmptyLatentImage = NODE_CLASS_MAPPINGS["EmptyLatentImage"]()
    
    values = input_params["input"]
    positive_prompt = values['positive_prompt']
    negative_prompt = values['negative_prompt']
    seed = values['seed']
    steps = values['steps']
    cfg = values['cfg']
    sampler_name = values['sampler_name']
    scheduler = values['scheduler']
    denoise = values['denoise']
    width = values['width']
    height = values['height']
    batch_size = values['batch_size']

    if seed == 0:
        random.seed(int(time.time()))
        seed = random.randint(0, 18446744073709551615)

    print(f"シード値: {seed}")
    print(f"生成中... (ステップ数: {steps})")
    
    positive = CLIPTextEncode.encode(clip, positive_prompt)[0]
    negative = CLIPTextEncode.encode(clip, negative_prompt)[0]
    latent_image = EmptyLatentImage.generate(width, height, batch_size=batch_size)[0]
    samples = KSampler.sample(unet, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise)[0]
    decoded = VAEDecode.decode(vae, samples)[0].detach()
    
    save_path = get_save_path(positive_prompt)
    Image.fromarray(np.array(decoded * 255, dtype=np.uint8)[0]).save(save_path)
    
    return save_path


def parse_aspect_ratio(aspect_ratio):
    """アスペクト比文字列から幅と高さを取得"""
    width, height = [int(x) for x in aspect_ratio.split("(")[0].strip().split("x")]
    return width, height


def main():
    # モデルをロード
    unet, clip, vae = load_models()
    
    # === 設定 ===
    positive_prompt = 'A photorealistic, ultra detailed, humorous scene on a bustling dutch street market. A tabby cat anthropomorphized, running on two legs while tightly hugging a large, shiny silver fish. The cat has a determined, dramatic facial expression with wide eyes and an open mouth, as if mid-shout. Behind the cat, a shocked fish vendor in an apron is chasing after it, yelling. Fresh fishes are laid out on a market stall to the right, displayed on ice. The background features open stalls, market signs, and a few bystanders reacting in surprise. Dynamic lighting, rich details, cinematic composition, freeze-frame action shot, expressive motion blur, '
    
    negative_prompt = 'low resolution, blurry subject, muddy focus, extreme motion blur, double exposure, ghosting, smearing, pixelated, jpeg artifacts, noise, banding  bad anatomy, deformed cat, extra legs, missing legs, extra tail, broken spine, twisted body, malformed face, misaligned eyes, bad mouth shape, extra limbs on human, fused fingers, broken hands  unnatural pose, stiff movement, floating subjects, wrong perspective, warped proportions, stretched cat, tiny head, giant head  dead fish look, deformed fish, unrealistic fish scales, melted texture, broken highlights, flat metal reflections  poor lighting, flat lighting, blown highlights, crushed shadows, incorrect shadows, inconsistent light direction  bad composition, off-center subject, awkward framing, cut off cat, cut off face, crowded scene, cluttered background, blocking foreground  low realism, cartoon, anime, illustration, painting, CGI look, game graphics, toy-like, plush-like fur  wrong setting, non-Dutch market, incorrect environment, indoor market, modern mall, supermarket aisles  bad emotion, neutral face, blank expression, lifeless eyes, no urgency  text, watermark, logo, captions, frame, borders'

    # アスペクト比オプション:
    # "1024x1024 ( 1:1 )", "1152x896 ( 9:7 )", "896x1152 ( 7:9 )", 
    # "1152x864 ( 4:3 )", "864x1152 ( 3:4 )", "1248x832 ( 3:2 )", 
    # "832x1248 ( 2:3 )", "1280x720 ( 16:9 )", "720x1280 ( 9:16 )", 
    # "1344x576 ( 21:9 )", "576x1344 ( 9:21 )"
    aspect_ratio = "1024x1024 ( 1:1 )"
    
    seed = 0  # 0の場合はランダム
    steps = 9
    cfg = 1.0
    denoise = 1.0
    batch_size = 1
    sampler_name = "euler"
    scheduler = "simple"
    
    width, height = parse_aspect_ratio(aspect_ratio)
    
    input_params = {
        "input": {
            "positive_prompt": positive_prompt,
            "negative_prompt": negative_prompt,
            "width": width,
            "height": height,
            "batch_size": batch_size,
            "seed": seed,
            "steps": steps,
            "cfg": cfg,
            "sampler_name": sampler_name,
            "scheduler": scheduler,
            "denoise": denoise,
        }
    }
    
    # 画像生成
    image_path = generate(unet, clip, vae, input_params)
    
    print(f"\n画像を保存しました: {image_path}")

if __name__ == "__main__":
    try:
        main()
    finally:
        # プログラムを確実に終了
        import gc
        gc.collect()
        
        # CUDAのキャッシュをクリア
        if torch.cuda.is_available():
            torch.cuda.synchronize()
            torch.cuda.empty_cache()
        
        # 強制終了(バックグラウンドスレッドも含めて終了)
        import os
        os._exit(0)

実行

実行してみましょう。

cd my-z-image/standalone
python z-image-turbo.py

ローカルで画像生成し放題の環境ができました!
お疲れさまでした。


アスペクト比を色々試した例

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?