快轉到主要內容

如何在Android手機Termux跑Stable Diffusion,用於AI繪圖

開源AI人工智慧應用 Stable Diffusion教學 Stable Diffusion Android Termux Python
🗓️ 民國112年 癸卯年
✍ 切換正體/簡體字
目錄

🇺🇸 English version

這篇文章記錄嘗試在Android手機跑Stable Diffusion,用於AI繪圖的過程,免Root。

Why? 因為你值得,寶礦力水得。

看到Github有人用8GB的樹莓派4跑Stable Diffusion。同為ARM架構的裝置,那照理說高階手機應該也可以如法炮製。

1. 系統資訊
#

  • 手機:Sony Xperia 5 II (Android 13)
  • CPU:高通Snapdragon 865 (Adreno 650)
  • RAM: 8GB
  • 準備30GB以上的空間,還有很快的4G網路。

2. 設定Linux環境
#

  1. 安裝 Termux

  2. 安裝 proot Debian環境,只要下載步驟1的最小系統,使用root帳號,不用裝桌面環境。

  3. 登入Proot Debian

proot-distro login debian --shared-tmp
  1. 安裝git, vim, Python, Pip
apt update
apt install git git-lfs vim python3 python3-pip
  1. 如果有需要可以安裝 Anaconda

3. 安裝Stable Diffusion
#

我下載的是最接近原始的版本,沒有圖形界面,要自己寫Pyhton程式呼叫Stable Diffusion算圖。

  1. 從runwayml的儲存庫下載全部模型,約30GB
git clone https://huggingface.co/runwayml/stable-diffusion-v1-5
cd stable-diffusion-v1-5
git lfs pull
  1. 接著安裝Python依賴套件
pip install --upgrade diffusers transformers accelerate ftfy xformers

4. 撰寫Stable Diffusion算圖程式
#

用預設的512x512像素下去算Termux會直接崩掉,恐怕需要16GB RAM的電競手機才負荷得了。我的8GB RAM手機最多試到320x320就是極限了(圖片長寬需為2的N次方)。

  1. 至開發人員選項,禁止一切程式背景運作,以將資源集中給Termux。另外啟用充電時螢幕不休眠的選項。

  2. Android預設會殺死佔用過多CPU的行程,參見 此篇於電腦安裝ADB工具,並執行以下指令,將max_phantom_processes的值設高一些。

adb shell "/system/bin/device_config set_sync_disabled_for_tests persistent; /system/bin/device_config put activity_manager max_phantom_processes 2147483647"
  1. 回到Termux,進入stable-diffusion-v1-5的上層目錄,新增app.py
cd ~
vim app.py
  1. 填入以下內容。
from diffusers import StableDiffusionPipeline, EulerDiscreteScheduler

# 使用本機模型
model_id = "./stable-diffusion-v1-5"

# 使用Euler採樣
scheduler = EulerDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")

# 啟用低RAM佔用,長寬320像素,步數50
pipe = StableDiffusionPipeline.from_pretrained(model_id, scheduler=scheduler, low_cpu_mem_usage=True, height=320, width=320, num_inference_steps=50)

# 規避NSFW偵測
pipe.safety_checker = lambda images, clip_input: (images, False)

# 算圖提示詞
prompt = "A victorian woman stands on grass field."

# 開始算圖,先測試使用CPU
image = pipe(prompt).images[0]

# 存檔
image.save("result.png")
  1. 開始算圖
python app.py
  1. 用CPU算大約需要30分鐘。

  2. 算圖時RAM幾乎是吃滿的狀態,Termux可能會隨時崩潰,不行的話就嘗試降低圖片長寬。

  3. 算好後,要取出proot裡的圖檔,將其移動至手機內部儲存空間。

mv result.png /sdcard
  1. 成品像這樣。算圖下限是256x256像素,在那之下的圖片基本不能看。

5. 使用Aderno GPU算圖
#

藉由實驗性的virglrenderer專案,就能讓Stable Diffusion吃到Vulkan,進而使用手機GPU加速算圖。

  1. 在Termux中編譯 virglrenderer,執行virgl伺服器。
MESA_NO_ERROR=1 MESA_GL_VERSION_OVERRIDE=4.0 GALLIUM_DRIVER=zink virgl_test_server --use-egl-surfaceless
  1. 登入Proot,在執行算圖程式前加上GALIIUM_DRIVER=virpipe讓其使用GPU,程式碼不用改。
GALLIUM_DRIVER=virpipe python app.py
  1. GPU加速大約能降低一點點算圖時間。

  2. 算出來的結果差距不大。

6. 在chroot裡跑Stable Diffusion
#

如果手機RAM不足,何不用SWAP就好了?

  1. 安裝 chroot Ubuntu

  2. 仿造上面的步驟安裝Python和Stable Diffusion,或者直接從proot-distro複製檔案 (路徑為/data/data/com.termux/files/usr/var/lib/proot-distro/installed-rootfs/ubuntu/root)。

  3. 建立8GB的SWAP檔案,這樣手機就有8+4+8=20GB的RAM了。如果不做此步驟,chroot硬算下去手機會直接重開機。

dd if=/dev/zero of=/swapfile bs=1M count=8192 status=progress
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
  1. 試著將圖片大小調整為標準的512x512像素,嘿,可以運算了。RAM吃多兇可想而知,所以得用ADB Shell或SSH進入chroot防止Termux崩掉。

  2. 算一小時後的成品。好像在說:你為什麼要花這麼多時間幹這種事情

參考資料
#

相關文章

Linux安裝 Style2Paints 半自動漫畫圖片上色軟體
開源AI人工智慧應用 AI影像處理 Image Inpainting
[Root] Termux:以原生效能在Android手機上跑Docker (紅米Note 5)
智慧型手機 Root與刷機 Termux Android Linux Kernel Docker Xiaomi
【免電腦】PTT網頁版認證電子信箱,解決手機無法登入的問題
Android

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。