2026年10月23日金曜日

stable-diffusion.cpp SYCLで動いた♪

一部機能をOFFにした状態でcmakeは通っていたのですが、さくっと処理の途中でエラーが発生して出力までたどり着かなかった(これが昨日まで)ので、じっくりと関連する部分のソースや、デバッグ出力を追加したりして動作確認をしていました。

パッと見 mmap関連だと思っていたものは、ちゃんとoffとなって動作していたのと、処理が行われても無視された形でスルーされていました。

なので何度か実行していたのですが、どうもメモリー確保が上手くいっていない様子。

実行時にfreeコマンドで空きメモリを確認しながら行いましたが、要求されているメモリ確保は余裕で行えるだけ空いているので何度か確認していましたが、メモリのフラグメンテーションが影響しているのでは?という結論に。そもそもSoC内蔵のiGPU自体、メモリの扱い方が結構何でもありな様で、明確なVRAMとメインメモリーとの差は実行時の処理速度の差はあるものの、コード上無視しても問題なかったりします(いまのところですがw)。処理速度は割り当てられた最初の2G程度以降は速度が遅いとか、共有メモリ部分はとてつもなく遅いとかいろいろあるようです。詳しい仕様は良く分かりませんけど…。

一般的にメインメモリー管理は処理言語で実装されていて、結構それなりにブラッシュアップされているはずなのと、ある程度は妥協するレベルなのですが、メモリーのデフラグとかガーベージコレクションとかも含めて実装されています。なので普通はメモリーが確保できないと言う時は、プロセスのメモリー使用限界に到達しているわけです。 

一方、oneAPI関連でZeroAPIとかいう低レベルメモリー管理機能APIを使ってなんとかintelに依存させようという悪あがき的な物があり、GGMLのSYCL方針としてはそのZeroAPIの対応もかなり入っています。宣伝文句的には「早い」「簡単」「便利」といった感じなのですが…ガーベージコレクションも対応しなきゃいけなさげ?コールするだけだとは思いますが、GGML側ではまだそこまで対応していません。なので、これをオフにすれば…と思い立ち、GGML_SYCL_USE_LEVEL_ZERO_API=0を付加して実行したところ、結構いい感じで実行されている感じに。(結局メモリー不足で落ちるわけですがw)

動いていそうなので、とりあえず旧型式(8/11のもの)で動いている形のz-imageで出力されたコマンドにZeroAPIをOFFにするパラメータを付加して実行したところ、見事出力されました。

が、なんか出力が違うw GGMLは同じソースとなっているのでstable-diffusion.cppでmodel毎に用意されているデフォルトのパラメータの変更による差異なのか、処理上の違いなのか…謎ですが、量子化Q2レベルで出力すると出力されたものがかなり乱れていたものが、結構マシに出力されるようになったりしました。

次にCPUのみで出力していたQwen Image 2.1 turboも同様にSYCLで実行したところ…量子化Q8_0だと絶望的にメモリが足りてない感じに。Q4_K_Mもだめ…Q2_Kで…何となく実行できる感じに。今まであまり気にしていなかったのですが、Qwen Image 2.1 turboは結構細かな動きが混ざっているようで…メインの処理に入る前にやたらとメモリの変動が…SYCLだとこの辺の処理が重たいのとメモリ使用量がCPUの倍ぐらい必要なままなので…。逆にここまで通ってしまえばvaeをCPU処理させれば確実に出力までたどり着く感じです。

少し出力させていますが、CPUでは1stepあたり180sかかっていたものが98s程度で動いているようなので単純に半分程度の時間になっているようです。intel_gpu_topで確認すると実行中の irqs/sの値が一桁、二桁に落ち込むので、処理を見直せばまだまだ早くなりそうです。まぁ本物のAI実行環境だと30sもあれば余裕で1024x1024が出力されるようですがw

そもそもメモリーが足りず、量子化Q8_0の動作が前提の環境だったのが、気づけば512x512が限界と言う状態で、何とかならんかと足掻いている最中だったりします。福音としてはkvバッファのサイズ指定やらなにやらが追加されているのでまだいけそうな部分はありそうですが、SYCLだと…その辺の実装は…まだまだ…というか内部はf32だけだったりするので「SYCL」を前提とすると、やはり巨大なメモリー空間が必要となるわけで…ってそこまで考えるとSYCLじゃなくていいんじゃね?ってなるという(笑) 

0 件のコメント:

コメントを投稿