Spaces:
Running on Zero
A newer version of the Gradio SDK is available: 6.24.0
Patch Notes – ZeroGPU Blackwell 対応
ZeroGPU のハードウェアが A100 → Half NVIDIA RTX Pro 6000 Blackwell に変更されたことに伴い、 PyTorch 2.11 / CUDA 13.0 環境で動作するよう以下の修正を適用した。
1. requirements.txt – torchao バージョン固定を解除
問題: torchao==0.11.0 が固定されていたが、最新の PEFT が torchao>=0.16.0 を要求するため起動時に ImportError が発生していた。
-torchao==0.11.0
+torchao>=0.16.0
2. app.py – AOTI コンパイル処理の削除
問題: spaces.aoti_capture / aoti_compile / aoti_apply は ZeroGPU 独自の実験的 API で、新しい Blackwell ハードウェア上で CUDA キャッシュアロケータのアサート失敗が発生していた。
RuntimeError: NVML_SUCCESS == r INTERNAL ASSERT FAILED at "CUDACachingAllocator.cpp":1165
対応: optimize_pipeline_ の import および呼び出しを削除。Lightning LoRA は 4 ステップ推論なので最適化なしでも実用速度を維持できる。
-from optimization import optimize_pipeline_
...
-optimize_pipeline_(pipe, image=[...], prompt="prompt")
3. app.py – アテンションプロセッサを FA3 → SDPA に変更
問題: QwenDoubleStreamAttnProcessorFA3 が kernels-community/vllm-flash-attn3 カーネルを使用しているが、このカーネルは Blackwell アーキテクチャ向けにコンパイルされておらず実行時に CUDA エラーが発生していた。
CUDA error: no kernel image is available for execution on the device
対応: PyTorch 組み込みの scaled_dot_product_attention(SDPA)を使う新しいプロセッサ QwenDoubleStreamAttnProcessorSDPA に切り替えた(詳細は項目 5 を参照)。
-from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
+from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorSDPA
...
-pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
+pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorSDPA())
4. qwenimage/pipeline_qwenimage_edit_plus.py – pos_embed 呼び出しを新 API に合わせる
問題: diffusers の QwenEmbedRope.forward の引数順が変更されていた。
| 旧 API(ローカル版) | 新 API(diffusers) | |
|---|---|---|
| 引数 | (video_fhw, txt_seq_lens, device) |
(video_fhw, device=None, max_txt_seq_len=None) |
旧 API で呼び出すと txt_seq_lens(list)が device の位置に渡され、lru_cache がリストをハッシュしようとして TypeError: unhashable type: 'list' が発生していた。
対応: max_txt_seq_len としてバッチ内最大値を渡すよう修正。pos_embed の呼び出しは 2 箇所(通常パス・uncond パス)を両方修正した。
+max_txt_seq_len = max(txt_seq_lens) if txt_seq_lens is not None else 0
-image_rotary_emb = self.transformer.pos_embed(img_shapes, txt_seq_lens, latents.device)
+image_rotary_emb = self.transformer.pos_embed(img_shapes, device=latents.device, max_txt_seq_len=max_txt_seq_len)
+max_negative_txt_seq_len = max(negative_txt_seq_lens) if negative_txt_seq_lens is not None else 0
-uncond_image_rotary_emb = self.transformer.pos_embed(img_shapes, negative_txt_seq_lens, latents.device)
+uncond_image_rotary_emb = self.transformer.pos_embed(img_shapes, device=latents.device, max_txt_seq_len=max_negative_txt_seq_len)
5. qwenimage/qwen_fa3_processor.py – SDPA プロセッサを追加
対応: QwenDoubleStreamAttnProcessorFA3 と同じ dual-stream 処理フローを保ちつつ、アテンション計算のみ SDPA に置き換えた QwenDoubleStreamAttnProcessorSDPA クラスを追加。
FA3 と SDPA でテンソルレイアウトが異なるため、入出力で transpose を行う:
- FA3:
(B, S, H, D_h)レイアウト - SDPA:
(B, H, S, D_h)レイアウト
# FA3 (変更前)
out = flash_attn_func(q, k, v, causal=False) # (B, S, H, D_h)
# SDPA (変更後)
out = F.scaled_dot_product_attention(
q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2), is_causal=False
).transpose(1, 2).contiguous() # back to (B, S, H, D_h)
既存の QwenDoubleStreamAttnProcessorFA3 クラスはファイルに残置(FA3 対応環境での利用余地)。
変更しなかったもの
pipe.transformer.__class__ = QwenImageTransformer2DModel— dual-stream アーキテクチャ((img_output, txt_output)タプル返却)に必要なため保持qwenimage/transformer_qwenimage.py— ローカル版のQwenEmbedRopeはpos_embedインスタンスには使われないが、QwenImageTransformer2DModelの forward メソッドのために保持