我們設計了一種新的架構,可以在條件文字到圖像生成中支援 10 多種控制類型,並且可以生成在視覺上可與中途相媲美的高解析度圖像。這個網路基於原始的 ControlNet 架構,我們提出了兩個新模組: 1 擴展原始 ControlNet 以使用相同的網路參數支援不同的圖像條件。 2 支援多種條件輸入而不增加計算卸載,這對於想要詳細編輯圖像的設計者來說尤其重要,不同的條件使用相同的條件編碼器,而不需要添加額外的計算或參數。我們對SDXL進行了充分的實驗,無論是控制能力或美觀評分都取得了優異的表現。我們將方法和模型發佈到開源社區,讓每個人都能享受。
如果您覺得有用,請給我一個star,非常感謝!
SDXL ProMax版本已經發布啦! !
很抱歉,由於項目的收支難以平衡,GPU資源被分配給其他更可能盈利的項目,SD3訓練停止,直到找到足夠的GPU支持,我會盡力找到 GPU 繼續訓練。如果這給您帶來不便,我深表歉意。我要感謝所有喜歡這個專案的人,你們的支持是我前進的動力
注意:我們將帶有 promax 後綴的 promax 模型放在同一個 Huggingface 模型倉庫中,稍後將添加詳細說明。
以下範例顯示從 1M 分辨率 --> 9M 分辨率
使用像novelai一樣的桶訓練,可以產生任何長寬比的高解析度影像
使用大量高品質數據(超過1000萬張圖像),數據集涵蓋多種情況
使用像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++
Comfyui 的 ControlNet++
發布培訓規格和培訓指南。
發布 arxiv 論文。
最重要的controlnet模型之一,我們在訓練這個模型時使用了很多技巧,與https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0一樣好,在姿態控制方面表現SOTA。為了讓openpose模型達到最佳效能,需要取代controlnet_aux套件中的draw_pose函數(comfyui有自己的controlnet_aux套件),具體參考Inference Scripts 。
最重要的controlnet模型之一,canny是與線稿、動畫線稿、mlsd混合訓練。處理任何細線的穩健性能,模型是降低畸形率的關鍵,建議使用細線重畫手/腳。
作為最重要的控制網模型之一,塗鴉模型可以支援任何線寬和任何線型。和https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0一樣,讓每個人都成為靈魂畫家。
注意:使用姿勢骨架控制人體姿勢,使用細線繪製手/腳細節以避免變形
注意:深度圖包含細節訊息,建議背景使用深度,前景使用姿勢骨架
注意:Scribble是一個強線條模型,如果你想畫一些輪廓不嚴格的東西,可以使用它。 Openpose + Scribble 讓您可以更自由地產生初始影像,然後您可以使用細線編輯細節。
我們收集了大量的高品質圖像。圖片經過嚴格的過濾和標註,圖片主題廣泛,包括攝影、動漫、自然、旅程等。
我們在 ControlNet++ 中提出了兩個新模組,分別稱為條件轉換器和控制編碼器。我們稍微修改了一個舊模組以增強其表示能力。此外,我們提出了一種統一的訓練策略,以實現單階段和多階段控制。
對於每個條件,我們為其分配一個控制類型id,例如openpose--(1, 0, 0, 0, 0, 0),深度--(0, 1, 0, 0, 0, 0),多重條件類似(openpose, depth) --(1, 1, 0, 0, 0, 0)。在控制編碼器中,控制類型 id 將轉換為控制類型嵌入(使用正弦位置嵌入),然後我們使用單一線性層來投影控制類型嵌入,使其與時間嵌入具有相同的暗度。將控制類型特徵加入時間嵌入以指示不同的控制類型,這個簡單的設定可以幫助ControlNet區分不同的控制類型,因為時間嵌入往往會對整個網路產生全域影響。無論是單條件或多條件,都有一個唯一的控制項類型id與之對應。
我們擴展 ControlNet 以使用相同網路同時支援多個控制輸入。條件轉換器用於組合不同的影像條件特徵。我們的方法有兩個主要創新,首先,不同的條件共享相同的條件編碼器,這使得網路更加簡單和輕量。這與 T2I 或 UniControlNet 等其他主流方法不同。其次,我們添加一個 Transformer 層來交換原始圖像和條件圖像的信息,而不是直接使用 Transformer 的輸出,而是用它來預測原始條件特徵的條件偏差。這有點像ResNet,我們透過實驗發現這個設定可以明顯提升網路的效能。
ControlNet 的原始條件編碼器是卷積層和 Silu 啟動的堆疊。我們不改變編碼器架構,只是增加轉換通道以獲得“胖”編碼器。這可以明顯提高網路的效能。原因是我們對所有圖像條件共享相同的編碼器,因此要求編碼器具有更高的表示能力。原始設定適用於單一條件,但不適用於 10 個以上條件。請注意,使用原始設定也可以,只是犧牲了一些影像生成品質。
使用單一條件進行訓練可能會受到資料多樣性的限制。例如,openpose 要求您使用人物圖像進行訓練,mlsd 要求您使用線條影像進行訓練,因此在產生看不見的物體時可能會影響效能。此外,不同條件的訓練難度不同,讓所有條件同時收斂並達到每個單一條件的最佳表現是很棘手的。最後,我們會傾向於同時使用兩個或多個條件,多條件訓練將使不同條件的整合更加平滑,增加網路的穩健性(因為單一條件學習的知識有限)。我們提出了一個統一的訓練階段來同時實現單一條件最佳化收斂和多條件融合。
ControlNet++ 需要將控制類型 ID 傳遞給網路。我們將10+個控制項合併為6種控制項類型,每種類型的意義如下:
0——開放姿勢
1——深度
2 -- 粗線(scribble/hed/softedge/ted-512)
3 -- 細線(canny/mlsd/ Lineart/animelinert/ted-1280)
4——正常
5——段
我們推薦Python版本>=3.8,您可以使用以下指令設定虛擬環境:
conda create -n controlplus python=3.8 conda 啟動 controlplus pip install -r 要求.txt
您可以在 https://huggingface.co/xinsir/controlnet-union-sdxl-1.0 中下載模型權重。任何新型號發布都會發佈在huggingface上,您可以關注https://huggingface.co/xinsir以獲取最新型號資訊。
我們為每個控制條件提供了推理腳本。請參閱它以了解更多詳細資訊。
存在一些預處理差異,為了獲得最佳的openpose-control效能,請執行以下操作:找到controlnet_aux套件中的util.py,將draw_bodypose函數替換為以下程式碼
def draw_bodypose(canvas: np.ndarray, keypoints: List[Keypoint]) -> np.ndarray: """ 在給定畫布上繪製代表身體姿勢的關鍵點和肢體。參數:canvas (np.ndarray): 3D numpy 陣列表示要在其上繪製身體關鍵點的畫布(圖像) (List[Keypoint]):表示要繪製的身體關鍵點的關鍵點物件清單返回: np.ndarray:表示修改後的畫布的3D numpy 數組。 若 max(W, H) < 500:比率 = 1.0 elif max(W, H) >= 500 且 max(W, H) < 1000:比率 = 2.0 elif max(W, H) >= 1000 且 max(W , H) < 2000: 比率= 3.0 elif max(W, H) >= 2000 且max(W, H) < 3000: 比率= 4.0 elif max(W, H) >= 3000 且max(W, H) < 4000: 比率= 5.0 elif max(W, H) >= 4000 且max(W, H) < 5000: 比率= 6.0 else: 比率= 7.0 棍寬= 4 肢體序列= [ [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], [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]] for (k1_index, k2_index), zip(limbSeq, Colors)中的顏色:keypoint1 = keypoints[k1_index - 1] keypoint2 = keypoints[k2_index - 1] 如果keypoint1 為None 或keypoint2 為None: continue 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) 長度= ((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(stickwidth * 比例)), int(角度), 0, 360, 1) cv2.fillConvexPoly(canvas ,多邊形,[int(float(c) * 0.6) for c in color]) for keypoint, color in zip(keypoints, Colors): if keypoint is None: continue x, y = keypoint.x, keypoint.y x = intpoint ( x * W) y = int(y * H) cv2.circle(canvas, (int(x), int(y)), int(4 * 比例), 顏色, 厚度=-1) 傳回畫布
對於單條件推理,您應該給出提示和控制圖像,更改python文件中的相應行。
python controlnet_union_test_openpose.py
對於多條件推理,應確保輸入的 image_list 與 control_type 相容,例如,如果要使用 openpose 和深度控制, image_list --> [controlnet_img_pose, controlnet_img_depth, 0, 0, 0, 0], control_type -- > [1, 1 , 0, 0, 0, 0]。有關更多詳細信息,請參閱 controlnet_union_test_multi_control.py。
理論上,你不需要為不同的條件設定條件尺度,網路被設計和訓練來自然地融合不同的條件。每個條件輸入的預設為1.0,與多條件訓練相同。但是,如果您想增加某些特定輸入條件的影響,您可以在條件轉換器模組中調整條件比例。在該模組中,輸入條件將與偏差預測一起添加到來源影像特徵中。乘以一定的比例會產生很大的影響(但可能會導致一些未知的結果)。
python controlnet_union_test_multi_control.py