【Intel Arc A770】【Diffusers】Intel GPUでFLUX.1-devのGGUFファイルを使う。

はじめに

PyTorchがIntel GPUに対応してもなかなかうまくいきませんでした。

このようなエラーに悩まされました。

RuntimeError: Required aspect fp64 is not supported on the device



今回、Diffusersのコードをたった二行書き換えただけで動作可能になりました。こちらをみてその方法を見つけました。
github.com

PC環境

Ubuntu 24.04
Intel Arc A770
Python 3.12
PyTorch 2.5.1+xpu

Python環境構築

pip install torch==2.5.1+xpu --index-url https://download.pytorch.org/whl/test/xpu
pip install gguf
pip install accelerate transformers protobuf sentencepiece

Diffusersはコードをダウンロードして一部書き換える必要があります。

git clone https://github.com/huggingface/diffusers

「src/diffusers/models/embeddings.py」の一部を以下のように書き換えます。

is_mps = ids.device.type == "mps"
freqs_dtype = torch.float32 if is_mps else torch.float64

is_mps_or_xpu = ids.device.type == "mps" or ids.device.type == "xpu"
freqs_dtype = torch.float32 if is_mps_or_xpu else torch.float64

その後インストールします。

pip install -e .

Pythonスクリプト

import torch
from diffusers import FluxPipeline, FluxTransformer2DModel, GGUFQuantizationConfig
from decorator import time_monitor
import gc

def flush():
    gc.collect()
    torch.xpu.empty_cache()

@time_monitor
def main():
    # downloaded from https://huggingface.co/city96/FLUX.1-dev-gguf
    gguf_file = "flux1-dev-Q4_K_S.gguf"
    model_id = "FLUX.1-dev"

    pipeline = FluxPipeline.from_pretrained(
            model_id,
            transformer=None,
            vae=None,
            torch_dtype=torch.bfloat16
    ).to("xpu")

    prompt = "A cat holding a sign that says hello world"

    with torch.no_grad():
        prompt_embeds, pooled_prompt_embeds, text_ids = pipeline.encode_prompt(
            prompt=prompt,
            prompt_2=None,
        )

    print("text_encoder:")
    print(f"torch.xpu.max_memory_allocated: {torch.xpu.max_memory_allocated()/ 1024**3:.2f} GB")

    del pipeline
    flush()

    transformer = FluxTransformer2DModel.from_single_file(
        gguf_file,
        quantization_config=GGUFQuantizationConfig(compute_dtype=torch.bfloat16),
        torch_dtype=torch.bfloat16
    )
    pipeline = FluxPipeline.from_pretrained(
        model_id,
        transformer=transformer,
        text_encoder=None,
        text_encoder_2=None,
        tokenizer=None,
        tokenizer_2=None,
        torch_dtype=torch.bfloat16
    ).to("xpu")

    image = pipeline(
        prompt_embeds=prompt_embeds,
        pooled_prompt_embeds=pooled_prompt_embeds,
        generator=torch.manual_seed(0)
    ).images[0]

    save_file = gguf_file.replace(".gguf", ".jpg")
    image.save(save_file)

    print("transformer:")
    print(f"torch.xpu.max_memory_allocated: {torch.xpu.max_memory_allocated()/ 1024**3:.2f} GB")

if __name__ == "__main__":
    main()

結果

text_encoder:
torch.xpu.max_memory_allocated: 9.32 GB

transformer:
torch.xpu.max_memory_allocated: 13.18 GB

time: 378.92 sec