3 điểm bởi GN⁺ 2023-08-21 | 1 bình luận | Chia sẻ qua WhatsApp
  • Đây là công cụ chạy suy luận mô hình Diffusion bằng C/C++ thuần túy, bao gồm các dòng SD, Flux và Wan, hướng tới một triển khai gọn nhẹ không có phụ thuộc bên ngoài
  • Phần triển khai dựa trên ggml và có cấu trúc Plain C/C++ hoạt động theo cách tương tự llama.cpp
  • Phạm vi mô hình được hỗ trợ được chia thành mô hình ảnh, mô hình chỉnh sửa ảnh và mô hình video, nhắm tới SD1.x, SD2.x, SDXL, SD3/SD3.5, FLUX, Qwen Image, Wan2.1/Wan2.2, LTX-2.3, v.v.
  • Phạm vi tính năng hỗ trợ gồm PhotoMaker, Control Net cho SD 1.5, LoRA theo cách của stable-diffusion-webui, LCM/LCM-LoRA, giải mã latent dựa trên TAESD, upscale ESRGAN, negative prompt và tokenizer hỗ trợ trọng số token
  • Các backend thực thi gồm CPU, CUDA, Vulkan, Metal, OpenCL và SYCL; CPU bao gồm hỗ trợ AVX, AVX2 và AVX512 trên kiến trúc x86
  • Các nền tảng được hỗ trợ là Linux, Mac OS, Windows và Android; trên Android, cách chạy là thông qua Termux và Local Diffusion
  • Các định dạng trọng số được hỗ trợ là .ckpt, .pth, .pt, .safetensors, .gguf; chế độ chuyển đổi sẽ chuyển trọng số mô hình sang .gguf hoặc .safetensors
  • Quy trình sử dụng cơ bản là tải binary dựng sẵn từ releases page hoặc build từ source, sau đó tải trọng số mô hình và chạy tạo ảnh theo dạng ./bin/sd-cli -m ../models/v1-5-pruned-emaonly.safetensors -p "a lovely cat"
  • Các tính năng tối ưu sử dụng bộ nhớ gồm Flash Attention và VAE tiling processing; việc tinh chỉnh backend batch khi chạy, tham số và cải thiện hiệu năng được tách thành hướng dẫn riêng
  • Các tùy chọn tái lập kết quả được chia thành --rng cuda--rng cpu, lần lượt hướng tới tính nhất quán với GPU RNG của stable-diffusion-webui và RNG của ComfyUI
  • Đầu ra PNG sẽ nhúng các tham số tạo sinh dưới dạng chuỗi văn bản tương thích webui
  • Có các dự án wrapper cho Golang, C#, Python, Rust và Flutter/Dart; Jellybox, Local Diffusion, LocalAI, KoboldCpp, v.v. sử dụng stable-diffusion.cpp làm backend tạo ảnh
  • Dự án đang được phát triển tích cực và API cũng như các tùy chọn dòng lệnh có thể thay đổi thường xuyên

1 bình luận

 
GN⁺ 2023-08-21
Các ý kiến trên Hacker News
  • Llama.cpp/ggml đặc biệt phù hợp với LLM
    Yêu cầu bộ nhớ lớn, lượng tử hóa hiệu quả, việc sinh token có tính tuần tự đáng ngạc nhiên và bị giới hạn bởi băng thông bộ nhớ nên rất hợp với CPU, thậm chí còn hợp hơn với kiểu suy luận pipeline CPU/GPU đặc trưng của ggml
    Nhưng Stable Diffusion thì khác. Lượng tử hóa không hiệu quả đến mức đó, UNet có khối lượng tính toán rất lớn, và tạo ảnh theo batch vẫn hiệu quả, hữu ích ngay cả với một người dùng đơn lẻ. Vì vậy nó phù hợp hơn với GPU/GPU tích hợp, và hưởng lợi lớn từ khả năng hack linh hoạt của bản triển khai Python
    Với Stable Diffusion, tôi nghĩ hướng đúng là dùng biên dịch machine learning để tạo file thực thi. AITemplate đã rất nhanh rồi https://github.com/VoltaML/voltaML-fast-stable-diffusion, TVM Vulkan cũng rất hứa hẹn nếu ai đó hoàn thiện tử tế bản demo https://github.com/mlc-ai/web-stable-diffusion
    Hơn nữa, phần lớn khả năng hack linh hoạt của bản PyTorch thuần vẫn được giữ lại

    • Dự án trên cũng hỗ trợ GPU ở một mức độ nào đó nếu truyền đúng các cờ biên dịch GGML
      Ví dụ khi biên dịch có hỗ trợ GGML_CUBLAS, và đạt mức tăng tốc khá ổn so với C/C++ thuần
    • Ngược lại, nó phù hợp với những người không có GPU NVIDIA với VRAM từ 6GB trở lên nhưng vẫn muốn thử nghịch các mạng nơ-ron này ở máy local
      Dù mất chút thời gian, vẫn có thể chạy trên laptop cũ
    • Nếu tôi nhớ không nhầm thì torch.compile cũng cho mức tăng tốc khá tốt, và tôi nhớ mình từng trực tiếp làm việc đó
      Tôi sẽ xem có tìm được số liệu không
  • Thật tuyệt khi họ còn triển khai cả CLIP
    Chỉ riêng việc tách nó ra rồi biên dịch thành bản WebAssembly cũng đã hay rồi
    Sửa: có vẻ đã có người tạo https://github.com/monatis/clip.cpp rồi. Giờ chỉ cần WebAssembly hóa nó

    • Nhân nói về CLIP, tôi luôn lo rằng khi OpenAI và Google chuyển sang chế độ cạnh tranh, liệu mô hình ở tầm CLIP tiếp theo có còn được công bố hay không
      Nghĩ đến khả năng đâu đó trong két bí mật đã có một mô hình tầm CLIP tiên tiến hơn thật đáng tiếc
      Sửa: ý tôi không phải là CLIP-2, mà là một bước tiến có mức độ quan trọng ngang với CLIP
  • Việc thiết lập dễ đến khó tin nên đây là lần đầu tôi thử ngay
    Tôi tò mò không biết tốc độ bao nhiêu mới là bình thường
    Trên Linux, tôi chạy trên AMD Ryzen 7 5700G với cmake .. -DGGML_OPENBLAS=ON, không có GPU rời mà chỉ có đồ họa tích hợp
    Khi chạy ./bin/sd -m ../models/sd-v1-4-ggml-model-f32.bin -p "a lovely cat", mỗi bước sampling mất khoảng 12 giây, toàn bộ quá trình sampling mất 246,40 giây
    Tôi muốn biết đây có phải hiệu năng kỳ vọng không
    Sửa: OpenBLAS chưa được cài nên cờ đó không có tác dụng

    • Cái này hay đấy. Về cơ bản nó làm đúng điều tôi từng muốn cách đây 1 năm[0]
      Khi đó hầu như mọi giải pháp đều đòi một đống phụ thuộc Python, cài đặt mất quá lâu rồi cuối cùng thất bại vì hết dung lượng ổ đĩa
      Thật sự, đúng nghĩa đen là thay thế vài gigabyte dung lượng ổ đĩa bằng một binary 799KB. Thêm nữa, nếu dùng định dạng Q8_0 có vẻ nhanh nhất, dữ liệu cũng tiết kiệm được khoảng 2,3GB
      Tuy nhiên ngoài kích thước ảnh mặc định 512x512 thì có vẻ có lỗi. Một số kích thước như 544x544 thường gây lỗi assert, các kích thước nhỏ hơn 512x512 đôi khi tạo ảnh rác, còn nhỏ hơn 384x384 thì gần như lúc nào cũng vậy
      [0] https://news.ycombinator.com/item?id=32555608
    • Bạn cần lượng tử hóa mô hình, nhưng khoảng 12 giây mỗi vòng lặp có vẻ đúng
    • Chỉ CPU, lượng tử hóa 8-bit, Intel Core i7 4770S, RAM DDR3 16GB, trên một PC không quạt 10 năm tuổi, mất 32 giây cho mỗi bước sampling và đầu ra vẫn bình thường
  • Các bản triển khai C/C++ liên quan đến AI có một sức hút đặc biệt nào đó
    Code trông gọn gàng và trực quan, khiến toàn bộ lĩnh vực AI có vẻ như có thể nắm bắt và học được
    Có phải vì hệ sinh thái Python quá lộn xộn không?

    • Viết lại nhìn chung giúp nâng cao chất lượng code, và thay các phụ thuộc bằng code tùy chỉnh chỉ làm đúng việc cần làm cũng nâng cao chất lượng code
      Phiên bản Python cũng dùng code C và C++ để tăng tốc, nhưng ở đây tất cả đều nằm trong một ngôn ngữ
      Có thể nói ba yếu tố tạo ra code gọn gàng đã cùng phát huy tác dụng
  • Thật vui khi thấy những người làm machine learning rời khỏi Python và dùng một ngôn ngữ có thể tận dụng phần cứng tối ưu, lại không cần phải dựng môi trường đặc biệt để build/chạy

    • So sánh này khá kỳ lạ
      Trước hết, dự án trong bài gốc không dùng GPU giống như llama.cpp, trong khi phần lớn mã machine learning bằng Python đều dùng GPU. Viết mã Python tận dụng GPU tối ưu không khó. Có thể gọi GPU là một môi trường đặc biệt để build/chạy, nhưng với bài toán này thì GPU phù hợp hơn rất nhiều
      Thứ hai, dự án trong bài gốc cũng giống llama.cpp: sau khi đã xác nhận rằng một mô hình cụ thể như Stable Diffusion/LLaMA hoạt động tốt, họ mới viết mã hiệu quả và chuyên biệt hóa cao. Ngược lại, nơi Python tỏa sáng là giai đoạn prototyping khi vẫn chưa tìm được mô hình phù hợp. Tôi vẫn chưa thấy việc prototyping trong C++ dễ và tiện đến mức đó
      Tôi không có ý hạ thấp công việc tuyệt vời mà nhóm llama.cpp đang làm trong mảng machine learning trên CPU. Chỉ là vấn đề họ giải quyết hoàn toàn khác nhau
    • Sẽ tuyệt hơn nhiều nếu mọi mô hình machine learning đều có một API suy luận C đơn giản, để có thể gọi trực tiếp từ gần như bất kỳ ngôn ngữ/nền tảng nào mà không phải vật lộn với mớ phụ thuộc và cấu hình môi trường hỗn loạn
    • Trong stack machine learning, các thành phần quan trọng về hiệu năng thực ra cũng đâu được triển khai bằng Python
      Bên trong từ lâu đã toàn là CUDA, C, C++
      Python chỉ là một lớp keo kết dính rất hiệu quả để nối tất cả lại với nhau
    • Thực sự biết ơn những người làm các dự án như thế này
      Đây là cách duy nhất tôi từng chạy được các mô hình này mà không gặp vấn đề đau đầu. Khác biệt quá lớn. CUDA với Linux cũng không ổn lắm, còn AMD với Windows thì thảm họa. Có lẽ không chỉ mình tôi gặp vậy
    • Thật thú vị khi CPU của tôi có thể chạy một số mô hình này ở dạng lượng tử hóa với tốc độ gần tương đương GPU
      Rốt cuộc tất cả chỉ là vấn đề băng thông bộ nhớ thôi sao?
      Kiến trúc GPU không chỉ có năng lực tính toán, mà còn đặt bộ nhớ làm việc gần các đơn vị tính toán. Mỗi đơn vị có bộ nhớ cục bộ được đồng bộ với bộ nhớ toàn cục. Đây có phải là một lý do lớn khiến GPU mạnh với các tác vụ kiểu này không?
  • Nhìn có vẻ là C++, vậy sao lại gọi là C/C++?

    • Theo tôi hiểu thì dependency nền tảng là ggml được viết bằng C
  • Hôm nay tôi thấy repo này, kéo về và build .dylib trên Mac, rồi dùng công cụ ffi-gen của Dart để tạo binding từ file header được cung cấp
    Tôi đang thử nghiệm cùng Flutter và dùng FFI để khỏi phải khởi chạy subprocess
    Kết quả là một cơn đau đầu dữ dội và một ứng dụng hỏng. Mai tỉnh táo hơn sẽ thử lại
    Dù vậy bản thân repo này rất tuyệt, và trên M1 chạy được với f16 trong chưa tới 10 phút

  • Nhìn các ví dụ về nhiều mức lượng tử hóa thì khá ấn tượng
    Chuyển từ f16 sang q8_0 trông giống thay đổi về hướng hơn là mất chất lượng. Kết quả q5_1 trông khó phân biệt với q8_0
    Ở các mô hình độ chính xác cao thì mất tính quyết định, nhưng thực tế có khả năng vẫn khá dùng được

  • Có benchmark không?

    • Vài người ở đây đã đo thời gian, và có vẻ tùy lượng tử hóa và phần cứng mà mất khoảng 15–20 giây mỗi iteration
      https://github.com/leejet/stable-diffusion.cpp/issues/1
    • Tôi đã biên dịch bằng lệnh cmake .. -DGGML_CUBLAS=ON -DCMAKE_CUDA_COMPILER=/opt/cuda/bin/nvcc và dùng NVIDIA GeForce RTX 2060 SUPER
      Mô hình đã được chuyển sang FP16
      Với lựa chọn này, thời gian mỗi iteration nằm trong khoảng 8,5–9 giây, và tổng thời gian để tạo một ảnh là khoảng 200 giây