เราออกแบบสถาปัตยกรรมใหม่ที่สามารถรองรับการควบคุมมากกว่า 10 ประเภทในการสร้างข้อความเป็นรูปภาพตามเงื่อนไข และสามารถสร้างภาพที่มีความละเอียดสูงซึ่งเทียบได้กับการมองเห็นระหว่างการเดินทาง เครือข่ายใช้สถาปัตยกรรม ControlNet ดั้งเดิม เราเสนอโมดูลใหม่สองโมดูลเพื่อ: 1 ขยาย ControlNet ดั้งเดิมเพื่อรองรับสภาพภาพที่แตกต่างกันโดยใช้พารามิเตอร์เครือข่ายเดียวกัน 2 รองรับอินพุตหลายเงื่อนไขโดยไม่ต้องเพิ่มออฟโหลดการคำนวณ ซึ่งเป็นสิ่งสำคัญอย่างยิ่งสำหรับนักออกแบบที่ต้องการแก้ไขภาพโดยละเอียด เงื่อนไขที่แตกต่างกันใช้ตัวเข้ารหัสเงื่อนไขเดียวกัน โดยไม่ต้องเพิ่มการคำนวณหรือพารามิเตอร์เพิ่มเติม เราทำการทดลอง SDXL อย่างละเอียดและบรรลุประสิทธิภาพที่เหนือกว่าทั้งในด้านความสามารถในการควบคุมและคะแนนด้านสุนทรียภาพ เราเผยแพร่วิธีการและโมเดลให้กับชุมชนโอเพ่นซอร์สเพื่อให้ทุกคนสามารถเพลิดเพลินได้
หากเห็นว่ามีประโยชน์กรุณาให้ดาวผมด้วย ขอบคุณมากครับ!!
รุ่น SDXL ProMax เปิดตัวแล้ว!!!,ขอให้สนุกนะ!!!
ฉันเสียใจที่เนื่องจากรายรับและรายจ่ายของโครงการนั้นยากต่อการรักษาสมดุล ทรัพยากร GPU ถูกกำหนดให้กับโครงการอื่น ๆ ที่มีแนวโน้มที่จะทำกำไรได้มากกว่า การฝึกอบรม SD3 จะหยุดลงจนกว่าฉันจะพบการสนับสนุน GPU เพียงพอ ฉันจะพยายามอย่างเต็มที่ ค้นหา GPU เพื่อฝึกต่อ หากสิ่งนี้ทำให้คุณไม่สะดวก ฉันต้องขออภัยอย่างจริงใจมา ณ ที่นี้ ฉันอยากจะขอบคุณทุกคนที่ชอบโครงการนี้ การสนับสนุนของคุณคือสิ่งที่ทำให้ฉันดำเนินต่อไป
หมายเหตุ: เราใส่โมเดล promax ที่มีคำต่อท้าย promax ไว้ใน repo โมเดล Huggingface เดียวกัน คำแนะนำโดยละเอียดจะถูกเพิ่มในภายหลัง
ตัวอย่างต่อไปนี้แสดงจากความละเอียด 1M --> ความละเอียด 9M
ใช้ Bucket Training เช่น Novai เพื่อสร้างภาพที่มีความละเอียดสูงในทุกอัตราส่วนภาพ
ใช้ข้อมูลคุณภาพสูงจำนวนมาก (มากกว่า 10000000 ภาพ) ชุดข้อมูลครอบคลุมสถานการณ์ที่หลากหลาย
ใช้พร้อมต์คำบรรยายใหม่ เช่น DALLE.3 ใช้ CogVLM เพื่อสร้างคำอธิบายโดยละเอียด ความสามารถในการติดตามพร้อมท์ที่ดี
ใช้เทคนิคที่มีประโยชน์มากมายระหว่างการฝึก รวมถึงแต่ไม่จำกัดเฉพาะการเพิ่มวันที่, การสูญเสียหลายรายการ, ความละเอียดหลายรายการ
ใช้พารามิเตอร์เกือบเหมือนกันเมื่อเทียบกับ ControlNet ดั้งเดิม ไม่มีการเพิ่มพารามิเตอร์เครือข่ายหรือการคำนวณอย่างชัดเจน
รองรับเงื่อนไขการควบคุมมากกว่า 10 แบบ ประสิทธิภาพไม่ลดลงอย่างเห็นได้ชัดในสภาวะใดเงื่อนไขหนึ่ง เมื่อเทียบกับการฝึกอบรมอย่างอิสระ
รองรับการสร้างเงื่อนไขหลายแบบ เรียนรู้การรวมเงื่อนไขระหว่างการฝึก ไม่จำเป็นต้องตั้งค่าไฮเปอร์พารามิเตอร์หรือพรอมต์การออกแบบ
เข้ากันได้กับรุ่น SDXL โอเพ่นซอร์สอื่น ๆ เช่น BluePencilXL, CounterfeitXL ใช้ได้กับ Lora รุ่นอื่นๆ
https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0
https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0
https://huggingface.co/xinsir/controlnet-tile-sdxl-1.0
https://huggingface.co/xinsir/controlnet-canny-sdxl-1.0
[07/06/2024] เปิดตัว ControlNet++
และรุ่นที่ฝึกล่วงหน้า
[07/06/2024] ปล่อยโค้ดอนุมาน (เงื่อนไขเดียวและหลายเงื่อนไข)
[07/13/2024] เปิดตัว ProMax ControlNet++
พร้อมฟังก์ชันการแก้ไขขั้นสูง
ControlNet++ สำหรับวิทยุ
ControlNet++ สำหรับ Comfyui
เผยแพร่รหัสการฝึกอบรมและคำแนะนำการฝึกอบรม
ปล่อยกระดาษ arxiv
หนึ่งในโมเดล controlnet ที่สำคัญที่สุด เราใช้เทคนิคมากมายในการฝึกโมเดลนี้ ดีพอๆ กันกับ https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0 ประสิทธิภาพของ SOTA ในการควบคุมท่าทาง เพื่อให้โมเดล openpose เข้าถึงประสิทธิภาพที่ดีที่สุด คุณควรแทนที่ฟังก์ชัน Draw_pose ในแพ็คเกจ controlnet_aux (comfyui มีแพ็คเกจ controlnet_aux ของตัวเอง) โปรดดูรายละเอียดที่ สคริปต์การอนุมาน
หนึ่งในโมเดลคอนโทรลเน็ตที่สำคัญที่สุด canny คือการฝึกแบบผสมกับ lineart, anime lineart, mlsd ประสิทธิภาพที่แข็งแกร่งในการจัดการกับเส้นบางๆ โมเดลนี้เป็นกุญแจสำคัญในการลดอัตราการผิดรูป แนะนำให้ใช้เส้นบางเพื่อวาดมือ/เท้าใหม่
หนึ่งในโมเดลคอนโทรลเน็ตที่สำคัญที่สุด โมเดล Scribble สามารถรองรับความกว้างของเส้นและประเภทของเส้นใดก็ได้ ดีไม่แพ้กัน https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0 ทำให้ทุกคนเป็นจิตรกรแห่งจิตวิญญาณ
หมายเหตุ: ใช้โครงร่างท่าทางเพื่อควบคุมท่าทางของมนุษย์ ให้ใช้เส้นบางเพื่อวาดรายละเอียดมือ/เท้าเพื่อหลีกเลี่ยงการเสียรูป
หมายเหตุ: รูปภาพเชิงลึกประกอบด้วยข้อมูลรายละเอียด ขอแนะนำให้ใช้ความลึกสำหรับพื้นหลัง และใช้โครงกระดูกสำหรับเบื้องหน้า
หมายเหตุ: Scribble เป็นรูปแบบเส้นที่ชัดเจน หากคุณต้องการวาดบางสิ่งที่มีโครงร่างที่ไม่เข้มงวด คุณสามารถใช้มันได้ Openpose + Scribble ช่วยให้คุณมีอิสระมากขึ้นในการสร้างภาพเริ่มต้น จากนั้นคุณสามารถใช้เส้นบางๆ เพื่อแก้ไขรายละเอียดได้
เรารวบรวมภาพคุณภาพสูงจำนวนมาก รูปภาพได้รับการกรองและใส่คำอธิบายประกอบอย่างจริงจัง รูปภาพครอบคลุมหัวข้อต่างๆ มากมาย รวมถึงภาพถ่าย อะนิเมะ ธรรมชาติ การเดินทางระหว่างทาง และอื่นๆ
เราเสนอโมดูลใหม่สองโมดูลใน ControlNet++ ชื่อ Condition Transformer และ Control Encoder ตามลำดับ เราได้แก้ไขโมดูลเก่าเล็กน้อยเพื่อเพิ่มความสามารถในการแสดง นอกจากนี้เรายังเสนอกลยุทธ์การฝึกอบรมแบบครบวงจรเพื่อให้เกิดการควบคุมแบบเดี่ยวและหลายรายการในขั้นตอนเดียว
สำหรับแต่ละเงื่อนไข เราจะกำหนดมันด้วยรหัสประเภทการควบคุม เช่น openpose--(1, 0, 0, 0, 0, 0), deep--(0, 1, 0, 0, 0, 0) หลายเงื่อนไขจะเป็นเช่น (เปิด, ลึก) --(1, 1, 0, 0, 0, 0) ใน Control Encoder รหัสประเภทการควบคุมจะถูกแปลงเป็นการฝังประเภทการควบคุม (โดยใช้การฝังตำแหน่งไซน์ซอยด์) จากนั้นเราจะใช้เลเยอร์เชิงเส้นเดี่ยวเพื่อควบคุมการฝังประเภทการควบคุมให้มีสลัวเท่ากันกับการฝังเวลา คุณลักษณะประเภทการควบคุมจะถูกเพิ่มลงในการฝังเวลาเพื่อระบุประเภทการควบคุมต่างๆ การตั้งค่าง่ายๆ นี้สามารถช่วยให้ ControlNet สามารถแยกแยะประเภทการควบคุมที่แตกต่างกันได้ เนื่องจากการฝังเวลามีแนวโน้มที่จะมีผลกระทบทั่วโลกในเครือข่ายทั้งหมด ไม่ว่าเงื่อนไขเดียวหรือหลายเงื่อนไข ก็จะมีรหัสประเภทการควบคุมเฉพาะที่สัมพันธ์กัน
เราขยาย ControlNet เพื่อรองรับอินพุตควบคุมหลายรายการพร้อมกันโดยใช้เครือข่ายเดียวกัน หม้อแปลงปรับสภาพใช้เพื่อรวมคุณสมบัติสภาพของภาพต่างๆ มีนวัตกรรมหลักสองประการเกี่ยวกับวิธีการของเรา ประการแรก เงื่อนไขที่แตกต่างกันใช้ตัวเข้ารหัสเงื่อนไขเดียวกัน ซึ่งทำให้เครือข่ายง่ายขึ้นและมีน้ำหนักเบา สิ่งนี้แตกต่างกับวิธีการทั่วไปอื่นๆ เช่น T2I หรือ UniControlNet ประการที่สอง เราเพิ่มเลเยอร์ทรานฟอร์เมอร์เพื่อแลกเปลี่ยนข้อมูลของภาพต้นฉบับและภาพสภาพ แทนที่จะใช้เอาท์พุตของหม้อแปลงโดยตรง เราจะใช้เลเยอร์นี้เพื่อคาดการณ์อคติของสภาพกับคุณสมบัติสภาพดั้งเดิม สิ่งนี้คล้ายกับ ResNet และเราทดลองพบว่าการตั้งค่านี้สามารถปรับปรุงประสิทธิภาพของเครือข่ายได้อย่างเห็นได้ชัด
ตัวเข้ารหัสสภาพเดิมของ ControlNet คือชุดของเลเยอร์ Conv และการเปิดใช้งาน Silu เราไม่เปลี่ยนสถาปัตยกรรมตัวเข้ารหัส เราเพียงเพิ่มช่อง Conv เพื่อให้ได้ตัวเข้ารหัส "อ้วน" ซึ่งสามารถเพิ่มประสิทธิภาพของเครือข่ายได้อย่างเห็นได้ชัด เหตุผลก็คือ เราใช้ตัวเข้ารหัสเดียวกันสำหรับทุกสภาพภาพ ดังนั้นจึงต้องการให้ตัวเข้ารหัสมีความสามารถในการนำเสนอที่สูงกว่า การตั้งค่าดั้งเดิมจะใช้ได้ดีสำหรับเงื่อนไขเดียว แต่ไม่ดีสำหรับเงื่อนไขมากกว่า 10 รายการ โปรดทราบว่าการใช้การตั้งค่าดั้งเดิมก็ใช้ได้เช่นกัน เพียงแต่ต้องเสียสละคุณภาพการสร้างภาพบางส่วน
การฝึกอบรมที่มีเงื่อนไขเดียวอาจถูกจำกัดด้วยความหลากหลายของข้อมูล ตัวอย่างเช่น openpose ต้องการให้คุณฝึกกับรูปภาพกับผู้คน และ mlsd ต้องการให้คุณฝึกกับรูปภาพที่มีเส้น ดังนั้นจึงอาจส่งผลต่อประสิทธิภาพเมื่อสร้างวัตถุที่มองไม่เห็น นอกจากนี้ ความยากในการฝึกเงื่อนไขที่แตกต่างกันนั้นแตกต่างกัน เป็นเรื่องยากที่จะให้เงื่อนไขทั้งหมดมาบรรจบกันในเวลาเดียวกัน และบรรลุประสิทธิภาพที่ดีที่สุดของแต่ละเงื่อนไข สุดท้ายนี้ เราจะมีแนวโน้มที่จะใช้สองเงื่อนไขขึ้นไปในเวลาเดียวกัน การฝึกอบรมแบบหลายเงื่อนไขจะทำให้การรวมเงื่อนไขต่างๆ เข้าด้วยกันได้อย่างราบรื่นยิ่งขึ้น และเพิ่มความทนทานของเครือข่าย (เนื่องจากเงื่อนไขเดียวเรียนรู้ความรู้ที่จำกัด) เราเสนอขั้นตอนการฝึกอบรมแบบรวมศูนย์เพื่อให้เกิดการผสมผสานที่เหมาะสมที่สุดสำหรับเงื่อนไขเดียวและการรวมหลายเงื่อนไขในเวลาเดียวกัน
ControlNet++ ต้องส่งรหัสประเภทการควบคุมไปยังเครือข่าย เรารวมการควบคุม 10+ เข้ากับการควบคุม 6 ประเภท ความหมายของแต่ละประเภทมีดังนี้:
0 -- เปิดท่า
1 -- ความลึก
2 -- เส้นหนา (เขียนลวกๆ/hed/softedge/ted-512)
3 -- เส้นบางๆ(canny/mlsd/lineart/animelineart/ted-1280)
4 -- ปกติ
5 -- ส่วน
เราขอแนะนำเวอร์ชันหลาม >= 3.8 คุณสามารถตั้งค่าสภาพแวดล้อมเสมือนได้โดยใช้คำสั่งต่อไปนี้:
conda create -n controlplus หลาม = 3.8 conda เปิดใช้งานการควบคุมบวก pip ติดตั้ง -r ข้อกำหนด.txt
คุณดาวน์โหลดน้ำหนักโมเดลได้ใน https://huggingface.co/xinsir/controlnet-union-sdxl-1.0 สินค้ารุ่นใหม่ๆ จะถูกเผยแพร่บน Huggingface คุณสามารถติดตาม https://huggingface.co/xinsir เพื่อรับข้อมูลโมเดลใหม่ล่าสุด
เราจัดเตรียมสคริปต์การอนุมานสำหรับเงื่อนไขการควบคุมแต่ละข้อ โปรดดูรายละเอียดเพิ่มเติม
มีความแตกต่างในการประมวลผลล่วงหน้าบางประการ เพื่อให้ได้ประสิทธิภาพการควบคุม openpose ที่ดีที่สุด โปรดทำดังต่อไปนี้: ค้นหา util.py ในแพ็คเกจ controlnet_aux แทนที่ฟังก์ชัน Draw_bodypose ด้วยโค้ดต่อไปนี้
def Draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint]) -> np.ndarray: """ วาดจุดสำคัญและแขนขาที่แสดงถึงท่าทางของร่างกายบนผืนผ้าใบที่กำหนด Args: canvas (np.ndarray): อาร์เรย์ 3D numpy เป็นตัวแทนของผืนผ้าใบ (รูปภาพ) ที่จะวาดจุดสำคัญของร่างกาย (รายการ [จุดสำคัญ]): รายการของวัตถุจุดสำคัญที่แสดงถึงจุดสำคัญของร่างกายที่จะเป็น วาดกลับ: np.ndarray: อาร์เรย์ 3D ที่แสดงผืนผ้าใบที่ถูกแก้ไขด้วยท่าทางที่วาด หมายเหตุ: ฟังก์ชันคาดว่าพิกัด x และ y ของจุดสำคัญจะถูกทำให้เป็นมาตรฐานระหว่าง 0 ถึง 1 """ H, W, C = ผ้าใบรูปทรง ถ้าสูงสุด(W, H) < 500: อัตราส่วน = 1.0 elif สูงสุด(W, H) >= 500 และสูงสุด(W, H) < 1000: อัตราส่วน = 2.0 elif สูงสุด(W, H) >= 1000 และสูงสุด(W , H) < 2000: อัตราส่วน = 3.0 elif สูงสุด(W, H) >= 2000 และสูงสุด(W, H) < 3000: อัตราส่วน = 4.0 elif สูงสุด(W, H) >= 3000 และสูงสุด(W, H) < 4000: อัตราส่วน = 5.0 elif สูงสุด(W, H) >= 4000 และสูงสุด(W, H) < 5000: อัตราส่วน = 6.0 อย่างอื่น: อัตราส่วน = 7.0 ความกว้างของแท่ง = 4 limbSeq = [ [2, 3], [2, 6], [3, 4], [4, 5], [6, 7], [7, 8], [2, 9], [9, 10], [10, 11], [2, 12], [12, 13], [13, 14], [2, 1], [1, 15], [15, 17], [1, 16], [16, 18] ] สี = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0 ], [0, 255, 0], [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85 , 0, 255], [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85]] สำหรับ (k1_index, k2_index), สีใน zip (limbSeq, สี): keypoint1 = จุดสำคัญ[k1_index - 1] keypoint2 = จุดสำคัญ[k2_index - 1] ถ้า keypoint1 เป็น None หรือ keypoint2 คือไม่มี: ดำเนินการต่อ Y = np.array([keypoint1.x, keypoint2.x]) * float(W) X = np.array([keypoint1.y, keypoint2.y]) * float(H) mX = np .mean(X) mY = np.mean(Y) length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 มุม = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) รูปหลายเหลี่ยม = cv2.ellipse2Poly((int(mY), int( mX)), (int(ความยาว / 2), int(ความกว้างของแท่ง * อัตราส่วน)), int(มุม), 0, 360, 1) cv2.fillConvexPoly(canvas, รูปหลายเหลี่ยม, [int(float(c) * 0.6) สำหรับ c ในสี]) สำหรับจุดสำคัญ, สีใน zip (จุดสำคัญ, สี): หากจุดสำคัญคือไม่มี: ดำเนินการต่อ x, y = keypoint.x, keypoint.y x = int( x * W) y = int(y * H) cv2.circle(canvas, (int(x), int(y)), int(อัตราส่วน 4 *), สี, ความหนา=-1) ส่งคืนแคนวาส
สำหรับการอนุมานเงื่อนไขเดียว คุณควรแสดงพรอมต์และอิมเมจควบคุม เปลี่ยนบรรทัดที่สอดคล้องกันในไฟล์หลาม
หลาม controlnet_union_test_openpose.py
สำหรับการอนุมานหลายเงื่อนไข คุณควรตรวจสอบให้แน่ใจว่าอินพุต image_list ของคุณเข้ากันได้กับ control_type ของคุณ ตัวอย่างเช่น หากคุณต้องการใช้ openpose และการควบคุมเชิงลึก image_list --> [controlnet_img_pose, controlnet_img_deep, 0, 0, 0, 0], control_type -- > [1, 1, 0, 0, 0, 0] โปรดดูรายละเอียดเพิ่มเติมที่ controlnet_union_test_multi_control.py
ตามทฤษฎีแล้ว คุณไม่จำเป็นต้องตั้งค่าระดับเงื่อนไขสำหรับเงื่อนไขที่แตกต่างกัน เครือข่ายได้รับการออกแบบและฝึกอบรมเพื่อหลอมรวมเงื่อนไขที่แตกต่างกันตามธรรมชาติ การตั้งค่าเริ่มต้นคือ 1.0 สำหรับแต่ละอินพุตเงื่อนไข และจะเหมือนกันกับการฝึกแบบหลายเงื่อนไข อย่างไรก็ตาม หากคุณต้องการเพิ่มผลกระทบสำหรับเงื่อนไขอินพุตบางอย่าง คุณสามารถปรับขนาดเงื่อนไขได้ใน Condition Transformer Module ในโมดูลนั้น เงื่อนไขอินพุตจะถูกเพิ่มให้กับคุณสมบัติรูปภาพต้นฉบับพร้อมกับการทำนายอคติ คูณด้วยสเกลที่กำหนดจะส่งผลมาก (แต่อาจไม่ทราบผล)
หลาม controlnet_union_test_multi_control.py