Chào mọi người!
Vậy là bạn muốn tự tạo một node tùy chỉnh hả? Bạn đã tìm kiếm trên mạng và thấy tài liệu quá ít hoặc khó hiểu?
Tôi thích ComfyUI lắm, nhưng phải nói thật: mặc dù đã ra mắt được vài tháng, tài liệu hướng dẫn về node tùy chỉnh của nó vẫn còn tệ hại, cấp x). Thậm chí có thể nói là “cấp độ quỷ dữ”.
Bạn có thể tìm thấy một video dài 50 phút (rất hay, mặc dù chưa đầy đủ) và là người mới bắt đầu, bạn không muốn nó dài như vậy đâu.
Bạn có thể tìm thấy những hướng dẫn chưa hoàn chỉnh, khiến bạn bối rối hơn là giúp đỡ.
Bạn có thể tình cờ tìm thấy một hướng dẫn về node tùy chỉnh… cho một phần mềm hoàn toàn khác x).
Bạn có thể gặp những người bảo bạn “cứ học code đi”, đó thực sự là điều cuối cùng mà một người mới bắt đầu muốn nghe, đặc biệt là nếu họ không biết nhiều về Python ^^’.
Nhưng đừng lo lắng. Bạn chỉ cần đợi người khác chịu khổ thay bạn và sẵn sàng chia sẻ kinh nghiệm của họ. May mắn cho bạn, đó là trường hợp của tôi. Điều đó có nghĩa là tôi đã phải chịu khổ vì bạn!
Tôi xin thề rằng trong 5 phút, bạn sẽ có một node tùy chỉnh sẵn sàng để sử dụng.
TẠO SCRIPT
Hãy bắt đầu ngay bằng cách vào thư mục node tùy chỉnh. Tạo một tệp văn bản mới ngay tại đây (KHÔNG trong một thư mục mới lúc này). Đặt phần mở rộng .py và bất kỳ tên nào bạn muốn (tránh khoảng trắng và các ký tự đặc biệt nhé). Sau đó mở nó ra.
Bất kỳ trình soạn thảo văn bản nào cũng hoạt động, nhưng tôi khuyên dùng Notepad++ vì nó hiểu cú pháp code.
Mở tệp của bạn, nó trống trơn. Chúng ta sẽ viết code để tạo một node tùy chỉnh xuất hiện trong Comfy!
… Nhưng trước tiên, chúng ta phải hiểu làm thế nào để đi từ cái này:
… đến cái kia:
Hãy phân tích một node là gì:
Node (bản thân cái hộp).
Một cái tên (thực ra là bốn tên, nhưng chúng ta sẽ xem xét sau)
Biến, hay widget.
Các chấm đầu vào.
Các chấm đầu ra.
Trong code Python, node được định nghĩa là một class. Tên class LUÔN LUÔN bắt đầu bằng một chữ cái viết hoa và LUÔN LUÔN là một từ duy nhất. Nó trông như thế này:
ComfyUI first custom node barebone – Pastebin.com
–
Sao chép và dán tất cả code đó vào tệp trống của bạn. Sau đó lưu nó và mở ComfyUI.
Nhấp đúp vào một khoảng trống trong workflow của bạn, sau đó gõ “Node”. Bạn sẽ thấy myNode trong danh sách! Chọn nó. Xin chúc mừng, bạn đã tạo node tùy chỉnh đầu tiên của mình!
… Nhưng hiện tại, nó không thực sự thú vị. Hãy thêm một vài widget nhé!
TẠO WIDGET
Các biến, hay widget, được định nghĩa sau dòng “required”. Nó trông như thế này:
“text”: (“STRING”, {“default”:”Hey Hey!”}),
Sao chép và dán dòng đó, sau đó thêm 16 dấu cách trước nó, trong code của bạn. Nó phải nằm giữa các dấu ngoặc liên quan đến từ “required”. Lưu nó, sau đó khởi động lại ComfyUI.
Nếu node của bạn chuyển sang màu đỏ và phần mềm báo lỗi, bạn đã không thêm đủ dấu cách hoặc bạn đã không sao chép dòng đó vào vùng required.
Nếu không, node tùy chỉnh của bạn sẽ biến thành thế này:
Tôi gọi widget là “biến”, vì bạn có thể thay đổi chúng theo cách thủ công. Nhấp vào widget, bạn có thể thay đổi văn bản.
TẠO INPUT
Bây giờ giả sử chúng ta muốn một input “thật”, ý tôi là một input làm cho một chấm xuất hiện. Nó siêu đơn giản! Các chấm input giống hệt như widget (vì widget thực sự cũng là input, nhưng hãy cứ coi chúng là những thứ riêng biệt trong đầu chúng ta!).
Bạn chỉ cần viết “forceInput”: True thay vì default.
Trong code của bạn, trong phần “required”, sao chép và dán dòng trước đó (bao gồm cả dấu cách trước nó!). Sau đó thay đổi tên (từ “text” thành “text2” chẳng hạn) và xóa tất cả phần “default”. Viết chữ in đậm ở trên thay thế.
Dòng của bạn sẽ thành thế này:
“text2”: (“STRING”, {“forceInput”: True}),
Hai từ đó khiến Comfy hiểu rằng đó là một chấm input thay vì một widget. Hãy kiểm tra xem nó có hoạt động không nhé! Khởi động lại Comfy. Bạn sẽ thấy node của bạn đã thay đổi…
…. Nhưng nó không hoạt động như mong muốn ^^’. Tính đến thời điểm hiện tại, nếu node tùy chỉnh của bạn đã có trong workflow của bạn, hành vi của nó sẽ không thể đoán trước khi thay đổi input/widget/output của nó.
Hiện tại thì nó là như vậy. Tôi trình bày điều này trong hướng dẫn đó vì bạn cần biết quy tắc này: bất cứ khi nào bạn làm việc trên một node tùy chỉnh, hãy luôn xóa nó khỏi workflow trước mỗi lần kiểm tra.
Quay lại ví dụ của chúng ta. Xóa node tùy chỉnh trong ComfyUI. Lúc nãy chúng ta nhấp đúp để tìm nó, nhưng bây giờ đừng làm vậy. Điều gì sẽ xảy ra nếu chúng ta muốn tìm nó trong menu ngữ cảnh thay thế? Hãy làm điều này!
Nhưng chúng ta tìm nó ở đâu? Để biết, hãy đọc code. Tìm dòng CATEGORY.
Đã hiểu chưa? Nếu bạn đã tìm thấy nó, bạn nhận thấy ví dụ của chúng ta nằm trong danh mục “image/mynode2”.
Trong ComfyUI, nhấp chuột phải vào workflow, sau đó nhấp vào image. Bạn sẽ tìm thấy danh mục tùy chỉnh của chúng ta, mynode2! Nhấp vào nó và đây là nơi bạn tìm thấy node nhỏ của chúng ta.
Chọn nó.
Bây giờ chúng ta đã có nó. Node tùy chỉnh có một chấm input tên là text2 (hoặc bất cứ thứ gì bạn gọi nó).
Bây giờ, nếu chúng ta không chỉ muốn làm việc với văn bản thì sao? Chúng ta sẽ để dành việc đó sau, nhưng hiện tại, hãy đọc lại code của chúng ta, bạn sẽ nhận thấy input/widget có một kiểu, trong trường hợp này: STRING. Bạn chuyển nó thành INT và điều đó biến input/widget đó thành một số nguyên.
Bây giờ bạn đã biết cách cung cấp input! Bước tiếp theo hiển nhiên là học cách xử lý output.
TẠO OUTPUT
Chúng được định nghĩa trong các dòng RETURN_TYPES và RETURN_LINES của class. Đúng vậy, tất cả chỉ cần hai dòng đó!
Trong code của bạn, điền vào dấu ngoặc đơn RETURN_TYPES với:
“STRING”,’INT’, ‘FLOAT’, ‘LATENT’
Bạn vừa định nghĩa bốn output và tôi nghĩ bạn có thể đoán kiểu của chúng! Nếu bạn muốn vui vẻ, bạn có thể thêm nhiều hơn. Có hai quy tắc cần nhớ:
1. Luôn viết các kiểu bằng chữ in hoa!
2. Đảm bảo sử dụng đúng kiểu!
Bạn có nhận thấy không? Các dấu nháy đơn không giống nhau từ output này sang output khác.Không có quy tắc nào về điều đó, vì vậy đừng lo lắng về nó. Các ký hiệu này có thể hoán đổi cho nhau.
Bạn cũng có thể thay đổi tên của từng output thành bất cứ thứ gì bạn muốn. Trong dòng RETURN_LINES, điền vào dấu ngoặc đơn với:
“TxtO”, “IntO”, “FloatO”, “Latent output. Really cool, huh?”
Bây giờ bạn phải cẩn thận rằng số lượng tên trong dòng đó phải khớp với số lượng kiểu output bạn đã định nghĩa. Hiểu chưa? Tốt.
Trong ComfyUI, xóa node tùy chỉnh của bạn và khởi động lại phần mềm. Đặt lại node tùy chỉnh.
Yeah! Các output xuất hiện! Lưu ý rằng chúng đã có màu sắc phù hợp. Output latent có màu hồng; và nếu bạn cố gắng đặt conditioning hoặc image output, chúng sẽ có màu cam và xanh lam rồi. Tương tự, các output không màu đã yêu cầu các node tương thích.
Bạn có thể thử ngay bây giờ: gắn output string vào một node liên quan đến văn bản hoặc thử với output latent.
ĐẶT TÊN CHO CÁC NODE
Chúng ta gần xong rồi! Bây giờ chúng ta phải xem xét phần cuối cùng của code: ánh xạ class và ánh xạ tên.
Dòng đầu tiên, ánh xạ class, là nơi bạn tạo một cặp giữa một class và tên của node của bạn.
NODE_CLASS_MAPPINGS = {
“My First Node”: MyNode
}
Giá trị đầu tiên là tên mà bạn muốn xuất hiện trong phần mềm, vì vậy nó có thể là bất cứ thứ gì, chỉ cần đảm bảo nó nằm trong dấu nháy đơn. Thứ hai phải là tên của class như được định nghĩa trong code.
Nếu bạn có nhiều node tùy chỉnh, mỗi node phải có một dòng ở đây, nơi bạn định nghĩa tên sẽ xuất hiện trong phần mềm và ghép nối nó với tên của class.
Tôi không chắc dòng thứ hai (ánh xạ tên) làm gì. Bạn thậm chí có thể để nó trống, nó không báo lỗi khi chạy chương trình. Tôi sẽ để ai đó hiểu biết hơn giải thích cho chúng ta ^^’.
VẤN ĐỀ CUỐI CÙNG
Bây giờ, có một vấn đề cuối cùng. Hiện tại, node tùy chỉnh của chúng ta nằm trong thư mục mặc định cho các node tùy chỉnh. Điều gì sẽ xảy ra nếu bạn muốn đặt nó vào thư mục riêng? Hãy thử xem.
Tạo một thư mục mới, kéo tệp script của bạn vào đó. Nếu bạn khởi động lại ComfyUI ngay bây giờ, nó sẽ báo lỗi.
Tại sao?
Bởi vì chương trình yêu cầu một tệp khởi tạo để hiểu rằng script trong thư mục đó phải được sử dụng.
Tại sao?
Bởi vì… bởi vì x). (Bởi vì Python là một đống shit nhưng chúng ta phải gắn bó với nó nên chúng ta phải chấp nhận nó vì nó có mặt ở khắp mọi nơi.)
Hãy làm điều này ngay bây giờ. Trong thư mục node tùy chỉnh của bạn, hãy tạo một tệp văn bản mới và gọi nó CHÍNH XÁC như sau:
__init__.py
Mở nó và sao chép và dán code này:
from .myfirstnode import MyNode
NODE_CLASS_MAPPINGS = { “MyNode”: MyNode }
NODE_DISPLAY_NAME_MAPPINGS = { “FirstNode”: “My First Node” }
__all__ = [‘NODE_CLASS_MAPPINGS’, ‘NODE_DISPLAY_NAME_MAPPINGS’]
–
Có một vài quy tắc cần hiểu ở đây:
-
Trong dòng đầu tiên, từ ngay sau dấu chấm phải là tên script của bạn.
-
Sau import trong dòng đầu tiên, bạn phải có danh sách tất cả các class bạn đã định nghĩa trong script python của mình, được phân tách bằng dấu phẩy.
-
Nếu bạn có nhiều script, bạn phải viết dòng đó nhiều lần, mỗi script một lần.
Ngược lại, đối với các dòng khác, bạn chỉ cần một dòng.
Dòng ánh xạ class node phải bao gồm tất cả các ánh xạ class bạn đã định nghĩa trong script của mình. Chỉ cần sao chép và dán chúng và phân tách chúng bằng dấu phẩy.
Ánh xạ tên hiển thị hoạt động tương tự.
Hai dòng này là bắt buộc trong tệp init. Lưu ý rằng chúng ghi đè mọi thứ đã được định nghĩa trong script gốc. Vì vậy, ngay khi node tùy chỉnh của bạn nằm trong thư mục riêng, bạn phải định nghĩa các cặp tên node/class trong tệp init.
Bạn không bao giờ được chạm vào dòng “all”.
KẾT LUẬN
Vậy là xong! Với điều này, bạn có thể tạo bất cứ thứ gì trong ComfyUI! Tất nhiên, mọi thứ chúng ta đã làm chỉ là những điều cơ bản.
Và sau đó, có phần chính! Bạn có thể sử dụng code để làm cho node đó làm bất cứ điều gì bạn muốn. Tất cả mọi hàm Python đều hoạt động! Và với Python, bạn thậm chí có thể sử dụng các ngôn ngữ khác như javascript (cần thiết cho các thứ trực quan).
Nhưng đó là điều bạn sẽ phải tự học. Lập trình là một ngôn ngữ; như vậy, nó cực kỳ đa dạng và bạn không bao giờ thực sự hiểu biết 100% về nó. Nhưng giống như một ngôn ngữ thực sự, bạn có thể bắt đầu với những thứ đơn giản ngay lập tức và học dần dần!
Tuy nhiên, tôi sẽ đưa ra một vài quy tắc về Python:
Khoảng trắng rất quan trọng!
KHÔNG BAO GIỜ sử dụng tab để thụt lề các dòng của bạn. Sử dụng nhiều dấu cách. Trong Notepad++, gõ dấu cách bốn lần cho mỗi lần thụt lề. KHÔNG BAO GIỜ sử dụng tab. Tôi đã dành ngày đầu tiên của năm để cố gắng sửa một code thực sự hoàn hảo ngoại trừ việc tôi sử dụng tab!!!
Đây là những quy tắc thuần túy của Python. Nhưng ComfyUI cũng có bộ quy tắc riêng. Thông qua hướng dẫn này, chúng ta đã xem xét rất nhiều trong số đó, nhưng đây là một số quy tắc khác:
-
Nếu bạn muốn tạo một GÓI node tùy chỉnh, bạn không cần có nhiều script. Điều quan trọng là bạn phải có một class CHO MỖI NODE TÙY CHỈNH.
-
Một class có input, output và ít nhất một hàm. Nó hiển thị trong code của chúng ta:
FUNCTION = “test”
Dòng này có nghĩa là node tùy chỉnh áp dụng hàm có tên là “test” được định nghĩa trong script này.
Để node tùy chỉnh của bạn thực sự làm điều gì đó, bạn cần đảm bảo hàm được gọi trong dòng này thực sự làm bất cứ điều gì bạn muốn làm.
Ví dụ, nếu đó là tổng của hai input, thì tổng phải được gọi bởi nó.
FUNCTION = “mysum”
def sum(self, a,b)
c = a+b
return c
Ví dụ code này SẼ KHÔNG HOẠT ĐỘNG vì hàm đó không phải là hàm được gọi cho node tùy chỉnh này. Tuy nhiên, bạn có thể tạo một hàm “mysum” cuối cùng gọi hàm sum(a,b).
3. Tôi nghĩ một hàm phải luôn có “self” làm đối số đầu tiên của nó. Tôi không chắc tại sao và tôi không biết liệu nó có cụ thể cho Comfy hay không, hay đó là một quy tắc chung cho Python. Dù sao, bất cứ khi nào bạn định nghĩa một hàm, đừng bao giờ quên đối số self!
Tôi mới chỉ chạm vào bề mặt, nhưng thông qua kinh nghiệm cá nhân, bạn sẽ đi xa hơn nhiều! Bây giờ tôi sẽ giới thiệu bạn đến hướng dẫn này:
https://github.com/chrisgoringe/Comfy-Custom-Node-How-To/wiki
Nó chưa hoàn chỉnh nên ban đầu nó có vẻ đáng sợ, nhưng nó chứa rất nhiều thông tin hữu ích liên quan đến việc viết code cho ComfyUI. Rốt cuộc, nó được viết bởi một người tự tạo node tùy chỉnh của riêng họ!
Tôi cũng sẽ chia sẻ một “mẫu” node tùy chỉnh:
https://drive.google.com/drive/folders/1IfETXm_WFKZNRT1mszXjF_46LxbnGmiA?usp=sharing
Đó là node tùy chỉnh mà chúng ta đã làm việc trong hướng dẫn này (với một số điều chỉnh nhỏ). Bất cứ khi nào bạn muốn bắt đầu lại từ đầu, chỉ cần giải nén nó vào thư mục custom_nodes và nó hoạt động ngay lập tức. Sau đó, bạn chỉ cần sửa đổi các script!
Cuối cùng, đây là một vài bài tập để bạn luyện tập. Viết lại node tùy chỉnh mà chúng ta vừa tạo và giải các bài toán này với nó.
-
Chuyển đổi một widget thành một chấm input.
-
Thêm ba output: một image, một conditioning, một model.
3)
Đây là code cho một node tùy chỉnh:
ComfyUI custom node barebone – Pastebin.com
–
Viết lại nó để làm cho nó hoạt động. Gợi ý: có ba lỗi cần sửa.
Chúc vui vẻ, và tôi hy vọng điều này giúp ích cho một số người sáng tạo ngoài kia ^^.
