เดโม Stable Diffusion บน WebGPU
(islamov.ai)- เดโมสร้างภาพด้วย Stable Diffusion ที่รันได้โดยตรงในเบราว์เซอร์ ทำงานบน WebGPU และ WebAssembly โดยไม่ต้องมีเซิร์ฟเวอร์แยก
- ใช้งานได้เมื่อเปิดใช้งานแฟล็ก "Experimental WebAssembly" และ "Experimental WebAssembly JavaScript Promise Integration (JSPI)" ใน Chrome เวอร์ชันล่าสุด
- รับค่า Prompt, Negative Prompt และจำนวน inference step เพื่อสร้างภาพ โดย ไฟล์โมเดลจะถูกแคช จึงไม่จำเป็นต้องดาวน์โหลดใหม่ทุกครั้ง
- เป็นผลงานที่ได้จากการแพตช์ onnxruntime, emscripten, binaryen เพื่อรองรับการจัดสรรหน่วยความจำเกิน 4GB และพอร์ต StableDiffusionPipeline ของ Python มาเป็น JS
- ปัจจุบันยังช้าเนื่องจากยังไม่รองรับมัลติเธรดและยังมีการคำนวณ WebGPU ที่ยังไม่ได้พัฒนา แต่มีแนวโน้มจะปรับปรุงได้ในอนาคตด้วย การทำ JS kernel และรองรับ memory64
ข้อกำหนดในการรัน
- ต้องเปิดใช้งานแฟล็ก Experimental WebAssembly และ Experimental WebAssembly JavaScript Promise Integration (JSPI) ในเบราว์เซอร์ Chrome เวอร์ชันล่าสุด
- Model files จะถูกแคชไว้ จึงไม่ต้องดาวน์โหลดใหม่เมื่อกลับมาเยี่ยมชมอีกครั้ง
อินพุตและลักษณะการทำงาน
- มีช่องอินพุตสำหรับ Prompt, Negative Prompt และจำนวน inference step
- ใช้ PNDM Scheduler ทำให้ step จริงจะถูกประมวลผลจากค่าอินพุต i เป็น i+1
- แต่ละ step ใช้เวลาประมาณ 1 นาที และต้องใช้เวลาเพิ่มอีกราว 10 วินาทีเพื่อรัน VAE decoder สำหรับสร้างภาพ
- หากเปิด DevTools ทิ้งไว้ ความเร็วโดยรวมจะช้าลงประมาณ 2 เท่า
- UNET ทำงานบน CPU เท่านั้น เร็วกว่า GPU 10% และเมื่อรันบน GPU จะให้ผลลัพธ์ไม่ถูกต้องจนแท็บเบราว์เซอร์ค้าง
- จำนวน step ขั้นต่ำเพื่อให้ได้ผลลัพธ์ที่พอรับได้คือ 20 แต่ถ้าเพื่อสาธิต 3 step ก็เพียงพอ
FAQ
-
ข้อผิดพลาด protobuf parsing failed
- ไปที่ Application → Storage ใน DevTools แล้วสั่ง "Clear site data"
-
ข้อผิดพลาด sbox_fatal_memory_exceeded
- เป็นสถานะที่ RAM ไม่เพียงพอ สำหรับการรัน SD ให้ลองรีโหลดแท็บหรือรีโหลดเบราว์เซอร์
-
วิธีการพัฒนา
- พอร์ต StableDiffusionPipeline ของ Python มาเป็น JS
- แพตช์ onnxruntime และ emscripten+binaryen (ชุดเครื่องมือคอมไพล์ WebAssembly) เพื่อรองรับการจัดสรรและใช้งานหน่วยความจำเกิน 4GB
- หาก pull request ที่เกี่ยวข้องถูกรวมเข้ารีลีสแล้ว ทุกคนก็จะสามารถคอมไพล์และรันโค้ดที่ใช้หน่วยความจำเกิน 4GB ในเบราว์เซอร์ได้
-
สาเหตุที่ช้า
- ยัง ไม่รองรับมัลติเธรด จึงใช้ CPU core ได้เพียงคอร์เดียว
- ไม่สามารถสร้างหน่วยความจำ 64 บิตผ่าน SharedArrayBuffer ที่มาจากตัวสร้าง WebAssembly.Memory ได้
- มีการเสนอเปลี่ยนสเปกของแฟล็ก "memory64" และหลังจากได้รับการยอมรับแล้วมีแผนจะแพตช์เอนจิน V8 เพื่อรองรับ
-
รันบน GPU ได้หรือไม่
- รันบน GPU ได้ แต่ WebGPU ของ onnxruntime ยังอยู่ในระยะเริ่มต้น จึงยังมีการคำนวณจำนวนมากที่ยังไม่ได้พัฒนา
- ข้อมูลจึงถูกส่งไปมาระหว่าง CPU ผ่าน JS อย่างต่อเนื่อง
- หากมีการทำ JS kernel สำหรับการคำนวณส่วนใหญ่แล้ว ความเร็วอาจเพิ่มขึ้นอย่างมาก
-
รันแบบโลคัลได้หรือไม่
- ได้ และโค้ดของหน้านี้มีให้ในรีโพซิทอรี stable-diffusion-webgpu-minimal
-
สามารถใช้ transformers.js รัน LLM ขนาดใหญ่ได้หรือไม่
- ใช้แพ็กเกจ onnxruntime ที่แพตช์ไว้ (@aislamov/onnxruntime-web64) ได้ แต่ไม่รับประกันว่าจะทำงานได้ในทุกกรณี
- บิลด์นี้จำกัดหน่วยความจำไว้ที่ 8GB จึงโหลดน้ำหนักโมเดลได้ประมาณ 4GB
-
แผน pull request ไปยังรีโพซิทอรี onnxruntime
- มีแผนดำเนินการ โดยนี่จะเป็นงานชิ้นที่สองต่อจากการเพิ่ม GPU acceleration ให้กับ node.js binding ก่อนหน้านี้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ทีม MLC ทำสิ่งนี้ให้รันได้ตั้งแต่เดือนมีนาคมแล้ว: https://github.com/mlc-ai/web-stable-diffusion
ที่น่าประทับใจกว่านั้นคือหลังจากนั้นยังเพิ่มการรองรับ โมเดลภาษาขนาดใหญ่ อีกหลายตัวด้วย: https://webllm.mlc.ai/
“โหลด 3.5GB และใช้ RAM 8GB”
น่าสนใจที่เบราว์เซอร์กลายมาเป็นแบบนี้แล้ว เว็บได้กลืนระบบปฏิบัติการ ไปแล้ว
ต่อให้ดาวน์โหลดมารันเองโดยไม่ใช้เบราว์เซอร์ ขนาดที่ต้องดาวน์โหลดและปริมาณ RAM ที่ใช้ก็คงแทบไม่ต่างกัน
การมอบประสบการณ์แบบนี้ผ่านเบราว์เซอร์มีความเรียบง่ายอยู่ในตัว และดูเหมือนไม่มีวิธีที่ง่ายกว่านี้ในการ รัน Stable Diffusion แล้ว จึงหวังว่าโปรเจกต์แบบนี้จะยังได้รับการสนับสนุนต่อไป
ถ้าต้องใช้ Chrome เวอร์ชันล่าสุดพร้อมเปิดแฟล็ก
Experimental WebAssemblyและExperimental WebAssembly JavaScript Promise Integration (JSPI)ก็คงต้องรอให้เข้า Firefox ก่อนchrome:flagsตามที่ขอใน Brave แล้ว แต่ก็ยังไม่ทำงาน ผมไม่เคยโหลด Chrome ลงบนเครื่อง M1 Mac เลย และตอนนี้ก็ไม่คิดจะเริ่มตรงนี้ก็มีทำไว้แล้วเหมือนกัน: https://websd.mlc.ai/#text-to-image-generation-demo
MLC ใช้ Apache TVM สำหรับ การสร้างโค้ด WebGPU และการจูนอัตโนมัติ และประสิทธิภาพก็ค่อนข้างดี
ผมรวม Stable Diffusion ของ MLC-AI เข้ากับเว็บไซต์ของตัวเองเป็น ตัวสร้างพื้นหลังแบบกำหนดเอง โดยดึงข้อมูลโมเดลมาจาก Hugging Face
https://dustinbrett.com/
งานที่ติด CPU น่าจะลองใช้ service worker เพื่อไม่ให้ main thread ค้าง
ต่อไปคือแชตบอตบน WebGPU ใช่ไหม? แบบ แชตสไตล์ ChatGPT ที่ใช้ GPU ของผมผ่านเบราว์เซอร์?
โมเดลภาษาขนาดใหญ่ยิ่งดีเท่าไรยิ่งกิน RAM/VRAM มาก จึงทำให้ รันบน WebGPU ได้ยากเป็นพิเศษ
มีทำไว้แล้ว
สงสัยว่าเอาไปใช้กับอะไรได้บ้าง?
เท่าที่ผมเข้าใจคือมันสร้างภาพในเบราว์เซอร์แทนที่จะทำบนเซิร์ฟเวอร์ สิ่งที่นึกออกคือไม่ต้องรีเฟรชหน้าเพื่อเปลี่ยนภาพหรือสร้างภาพใหม่
ถ้าอย่างนั้นก็อาจหมายถึงเว็บไซต์ที่ดีไซน์ภาพเปลี่ยนแบบเรียลไทม์ได้ และถ้ามันเปลี่ยนในเชิงฟังก์ชันได้อย่างมีนัยสำคัญก็น่าจะเท่มาก แค่ยังไม่แน่ใจว่า Stable Diffusion จะมีประโยชน์แค่ไหนกับการสร้างคอมโพเนนต์ UI หรือองค์ประกอบภาพของเว็บไซต์
พรอมป์ตที่อ่อนไหวจะไม่รั่วไหลไปถึงคนอื่นที่อยู่ระยะไกล
มีตัวเลขเปรียบเทียบประสิทธิภาพบน WebGPU กับการรันแบบ native ไหม?
ดูเหมือนว่างาน GPU สำหรับ VAE ส่วนใหญ่ทำไว้แล้ว แต่ของ UNET ยังไม่เป็นแบบนั้น ในกรณีหลัง เบราว์เซอร์ยังคงโยนข้อมูลไปมาระหว่าง GPU กับ CPU ทุกขั้นตอน
ถ้าเร็วพอ ก็น่าจะใช้เรนเดอร์ภาพแบบ local สำหรับการใช้งานส่วนบุคคลได้ เว็บไซต์อาจ ส่งแค่พรอมป์ต แล้วให้เรนเดอร์ภาพต่างกันไปตามผู้ใช้แต่ละคน
ถ้าเป็นแบบนั้น ลิขสิทธิ์จะเป็นอย่างไร? ตัวโมเดลเองมีลิขสิทธิ์ไหม หรือระบบทั้งหมดจะพังทลาย?
และผมคิดว่านักออกแบบเว็บจำนวนมากคงไม่ยอมรับความเสี่ยงที่โมเดลจะตีความพรอมป์ตผิด สร้างผลลัพธ์บิดเบี้ยวอย่างนิ้วเกินหรือขาด หรือเผลอสร้างเนื้อหาเชิงเพศหรือความรุนแรงในบริบทที่ไม่ตั้งใจ
ทุกวันนี้โมเดลสร้างภาพจำนวนมากมักต้องเลือกภาพที่ดีที่สุดจากอย่างน้อยสิบภาพขึ้นไป และภาพที่คัดทิ้งไปนั้นอาจแย่มากจริง ๆ
ถ้าจะให้เว็บไซต์มีภาพประกอบแบบไดนามิกเป็นเรื่องปกติในชีวิตประจำวัน คุณภาพและความคาดเดาได้ของโมเดล จะต้องสูงกว่าตอนนี้มาก
แต่ก็ไม่ได้อยากบอกว่าไม่มีวันไปถึงจุดนั้น เพราะโมเดลรุ่นใหม่ ๆ ก็ทำสิ่งที่เมื่อไม่กี่ปีก่อนยังถูกมองว่านึกไม่ถึงได้แล้ว ลองเทียบกับ https://xkcd.com/1425/ ดู สำหรับผู้อ่านอายุน้อย การจะอธิบายบริบทของมุกนั้นอาจกลายเป็นเรื่องยากไปแล้ว!