Commit 133c21e2 authored by chenpangpang's avatar chenpangpang
Browse files

feat: 初始提交

parent c412fc14
Pipeline #1470 failed with stages
in 0 seconds
.idea
chenyh
This diff is collapsed.
{
"last_node_id": 40,
"last_link_id": 56,
"nodes": [
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
600,
420
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 38
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"path/to/images",
"direct_Input"
]
},
{
"id": 31,
"type": "Load CheckPoint DragNUWA",
"pos": [
940,
580
],
"size": {
"0": 330,
"1": 140
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "model",
"type": "DragNUWA",
"links": [
39
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Load CheckPoint DragNUWA"
},
"widgets_values": [
"dragnuwa-svd-pruned.fp16.safetensors",
"576x320",
14
]
},
{
"id": 33,
"type": "ImageScale",
"pos": [
1290,
580
],
"size": {
"0": 240,
"1": 140
},
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 56,
"slot_index": 0
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
40
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageScale"
},
"widgets_values": [
"nearest-exact",
576,
320,
"disabled"
]
},
{
"id": 36,
"type": "PreviewImage",
"pos": [
190,
400
],
"size": {
"0": 390,
"1": 860
},
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 45
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 5,
"type": "BaseModel_Loader_fromhub",
"pos": [
190,
290
],
"size": {
"0": 390,
"1": 60
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
6
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_fromhub"
},
"widgets_values": [
"SG161222/RealVisXL_V3.0"
]
},
{
"id": 28,
"type": "ImageBatch",
"pos": [
600,
1210
],
"size": {
"0": 320,
"1": 50
},
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "image1",
"type": "IMAGE",
"link": 37
},
{
"name": "image2",
"type": "IMAGE",
"link": 36
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
38,
45
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageBatch"
}
},
{
"id": 26,
"type": "LoadImage",
"pos": [
-140,
770
],
"size": {
"0": 310,
"1": 490
},
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
36
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"u=2159291575,1324293690&fm=253&fmt=auto&app=138&f=JPEG.webp",
"image"
]
},
{
"id": 3,
"type": "LoadImage",
"pos": [
-140,
290
],
"size": {
"0": 310,
"1": 430
},
"flags": {},
"order": 3,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
37
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download.jpg",
"image"
]
},
{
"id": 6,
"type": "PhotoMakerAdapter_Loader_fromhub",
"pos": [
600,
290
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 6
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
33
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_fromhub"
},
"widgets_values": [
"TencentARC/PhotoMaker",
"photomaker-v1.bin"
]
},
{
"id": 39,
"type": "PreviewImage",
"pos": [
940,
290
],
"size": {
"0": 350,
"1": 246
},
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 55
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 2,
"type": "Prompt_Styler",
"pos": [
600,
550
],
"size": {
"0": 320,
"1": 230
},
"flags": {},
"order": 4,
"mode": 0,
"outputs": [
{
"name": "positive_prompt",
"type": "STRING",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative_prompt",
"type": "STRING",
"links": [
2
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "Prompt_Styler"
},
"widgets_values": [
"a woman img, cute face portrait, ",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Disney Charactor"
]
},
{
"id": 34,
"type": "VHS_VideoCombine",
"pos": [
-144,
1309
],
"size": [
1670,
1200.6666666666665
],
"flags": {},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 42,
"slot_index": 0
},
{
"name": "audio",
"type": "VHS_AUDIO",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 10,
"loop_count": 0,
"filename_prefix": "DN_Zho",
"format": "video/h264-mp4",
"pix_fmt": "yuv420p",
"crf": 19,
"save_metadata": true,
"pingpong": false,
"save_output": true,
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "DN_Zho_00011.mp4",
"subfolder": "",
"type": "output",
"format": "video/h264-mp4"
}
}
}
},
{
"id": 32,
"type": "DragNUWA Run",
"pos": [
1310,
290
],
"size": {
"0": 220,
"1": 240
},
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "DragNUWA",
"link": 39
},
{
"name": "image",
"type": "IMAGE",
"link": 40,
"slot_index": 1
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
42
],
"shape": 3
}
],
"properties": {
"Node name for S&R": "DragNUWA Run"
},
"widgets_values": [
"[[[282,152],[270,142]],[[316,154],[329,147]],[[262,123],[254,112]],[[336,133],[345,121]],[[278,86],[279,93]],[[332,92],[334,101]],[[274,112],[271,103]],[[328,119],[333,110]],[[208,164],[195,160]],[[359,158],[364,169]],[[217,225],[207,207]],[[370,217],[369,201]],[[309,155],[322,149]],[[287,155],[276,146]],[[329,98],[334,108],[341,95]],[[282,89],[273,102],[269,89]],[[208,230],[195,213]],[[381,229],[393,211]],[[311,260],[337,245]],[[241,261],[215,247]],[[366,219],[376,193]],[[191,226],[176,206]],[[212,128],[214,140]],[[337,125],[339,138]],[[198,179],[207,163]],[[353,171],[347,157]],[[239,119],[247,129]],[[309,115],[304,129]],[[100,224],[93,239]],[[451,218],[467,227]]]",
1,
2,
false,
"X://path/to/optical_flow"
]
},
{
"id": 1,
"type": "NEW_PhotoMaker_Generation",
"pos": [
600,
830
],
"size": {
"0": 320,
"1": 330
},
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 33
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 5,
"slot_index": 1
},
{
"name": "positive",
"type": "STRING",
"link": 1,
"widget": {
"name": "positive"
}
},
{
"name": "negative",
"type": "STRING",
"link": 2,
"widget": {
"name": "negative"
}
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
54
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "NEW_PhotoMaker_Generation"
},
"widgets_values": [
"",
"",
1,
20,
50,
5,
1280,
768,
792828850907860,
"fixed"
]
},
{
"id": 35,
"type": "Preview Chooser",
"pos": [
940,
770
],
"size": {
"0": 590,
"1": 490
},
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 54
},
{
"name": "latents",
"type": "LATENT",
"link": null
}
],
"outputs": [
{
"name": "images",
"type": "IMAGE",
"links": [
55,
56
],
"shape": 3,
"slot_index": 0
},
{
"name": "latent",
"type": "LATENT",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "Preview Chooser"
},
"widgets_values": [
"Always pause",
1,
"",
""
]
}
],
"links": [
[
1,
2,
0,
1,
2,
"STRING"
],
[
2,
2,
1,
1,
3,
"STRING"
],
[
5,
4,
0,
1,
1,
"IMAGE"
],
[
6,
5,
0,
6,
0,
"MODEL"
],
[
33,
6,
0,
1,
0,
"MODEL"
],
[
36,
26,
0,
28,
1,
"IMAGE"
],
[
37,
3,
0,
28,
0,
"IMAGE"
],
[
38,
28,
0,
4,
0,
"IMAGE"
],
[
39,
31,
0,
32,
0,
"DragNUWA"
],
[
40,
33,
0,
32,
1,
"IMAGE"
],
[
42,
32,
0,
34,
0,
"IMAGE"
],
[
45,
28,
0,
36,
0,
"IMAGE"
],
[
54,
1,
0,
35,
0,
"IMAGE"
],
[
55,
35,
0,
39,
0,
"IMAGE"
],
[
56,
35,
0,
33,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
{
"last_node_id": 18,
"last_link_id": 18,
"nodes": [
{
"id": 14,
"type": "Ref_Image_Preprocessing",
"pos": [
1540,
2590
],
"size": {
"0": 330,
"1": 82
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 14,
"slot_index": 0
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
13
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"/content/ComfyUI/output",
"multiple"
]
},
{
"id": 15,
"type": "LoadImage",
"pos": [
1130,
2570
],
"size": {
"0": 390,
"1": 510
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
14
],
"shape": 3
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download (1).jpg",
"image"
]
},
{
"id": 17,
"type": "BaseModel_Loader_fromhub",
"pos": [
1130,
2460
],
"size": [
390,
60
],
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
16
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_fromhub"
},
"widgets_values": [
"SG161222/RealVisXL_V3.0"
]
},
{
"id": 18,
"type": "PhotoMakerAdapter_Loader_fromhub",
"pos": [
1540,
2460
],
"size": {
"0": 330,
"1": 82
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 16
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
18
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_fromhub"
},
"widgets_values": [
"TencentARC/PhotoMaker",
"photomaker-v1.bin"
]
},
{
"id": 16,
"type": "PreviewImage",
"pos": [
1890,
2460
],
"size": {
"0": 360,
"1": 620
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 15
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 13,
"type": "PhotoMaker_Generation",
"pos": [
1540,
2720
],
"size": {
"0": 330,
"1": 360
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 18
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 13
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
15
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMaker_Generation"
},
"widgets_values": [
"a woman img, retro futurism, retro game",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Cinematic",
20,
50,
5,
363594486247783,
"fixed",
768,
1280
]
}
],
"links": [
[
13,
14,
0,
13,
1,
"IMAGE"
],
[
14,
15,
0,
14,
0,
"IMAGE"
],
[
15,
13,
0,
16,
0,
"IMAGE"
],
[
16,
17,
0,
18,
0,
"MODEL"
],
[
18,
18,
0,
13,
0,
"MODEL"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
{
"last_node_id": 18,
"last_link_id": 17,
"nodes": [
{
"id": 5,
"type": "LoadImage",
"pos": [
290,
1220
],
"size": {
"0": 390,
"1": 510
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
],
"shape": 3
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download (1).jpg",
"image"
]
},
{
"id": 1,
"type": "BaseModel_Loader_local",
"pos": [
290,
1110
],
"size": {
"0": 390,
"1": 60
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
1
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_local"
},
"widgets_values": [
"sd_xl_base_1.0.safetensors"
]
},
{
"id": 6,
"type": "PreviewImage",
"pos": [
1050,
1110
],
"size": [
360,
620
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 5
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 2,
"type": "PhotoMakerAdapter_Loader_local",
"pos": [
700,
1110
],
"size": {
"0": 330,
"1": 82
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 1
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
17
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_local"
},
"widgets_values": [
"/content/ComfyUI/custom_nodes/ComfyUI-PhotoMaker/models",
"photomaker-v1.bin"
]
},
{
"id": 3,
"type": "PhotoMaker_Generation",
"pos": [
700,
1370
],
"size": {
"0": 330,
"1": 360
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 17
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 3
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMaker_Generation"
},
"widgets_values": [
"a woman img, retro futurism, retro game",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Photographic (Default)",
20,
50,
5,
363594486247783,
"fixed",
768,
1280
]
},
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
700,
1240
],
"size": {
"0": 330,
"1": 82
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 4,
"slot_index": 0
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
3
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"/content/ComfyUI/output",
"multiple"
]
}
],
"links": [
[
1,
1,
0,
2,
0,
"MODEL"
],
[
3,
4,
0,
3,
1,
"IMAGE"
],
[
4,
5,
0,
4,
0,
"IMAGE"
],
[
5,
3,
0,
6,
0,
"IMAGE"
],
[
17,
2,
0,
3,
0,
"MODEL"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
{
"last_node_id": 25,
"last_link_id": 31,
"nodes": [
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
610,
420
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 4
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"path/to/images",
"direct_Input"
]
},
{
"id": 6,
"type": "PhotoMakerAdapter_Loader_fromhub",
"pos": [
610,
290
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 6
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
14
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_fromhub"
},
"widgets_values": [
"TencentARC/PhotoMaker",
"photomaker-v1.bin"
]
},
{
"id": 5,
"type": "BaseModel_Loader_fromhub",
"pos": [
270,
290
],
"size": {
"0": 320,
"1": 60
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
6
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_fromhub"
},
"widgets_values": [
"SG161222/RealVisXL_V3.0"
]
},
{
"id": 3,
"type": "LoadImage",
"pos": [
270,
400
],
"size": {
"0": 320,
"1": 440
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download.jpg",
"image"
]
},
{
"id": 10,
"type": "LoRALoader",
"pos": [
950,
290
],
"size": {
"0": 315,
"1": 82
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 14
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
17
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LoRALoader"
},
"widgets_values": [
"xl_more_art-full.safetensors",
0.7000000000000001
]
},
{
"id": 1,
"type": "NEW_PhotoMaker_Generation",
"pos": [
950,
420
],
"size": {
"0": 320,
"1": 420
},
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 17
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 5,
"slot_index": 1
},
{
"name": "positive",
"type": "STRING",
"link": 1,
"widget": {
"name": "positive"
}
},
{
"name": "negative",
"type": "STRING",
"link": 2,
"widget": {
"name": "negative"
}
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
31
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "NEW_PhotoMaker_Generation"
},
"widgets_values": [
"",
"",
4,
20,
50,
5,
1024,
1024,
0,
"fixed"
]
},
{
"id": 25,
"type": "PreviewImage",
"pos": [
1295,
290
],
"size": [
530,
550
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 31
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 2,
"type": "Prompt_Styler",
"pos": [
610,
550
],
"size": [
320,
290
],
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "positive_prompt",
"type": "STRING",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative_prompt",
"type": "STRING",
"links": [
2
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "Prompt_Styler"
},
"widgets_values": [
"a woman img, retro futurism, retro game",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Photographic (Default)"
]
}
],
"links": [
[
1,
2,
0,
1,
2,
"STRING"
],
[
2,
2,
1,
1,
3,
"STRING"
],
[
4,
3,
0,
4,
0,
"IMAGE"
],
[
5,
4,
0,
1,
1,
"IMAGE"
],
[
6,
5,
0,
6,
0,
"MODEL"
],
[
14,
6,
0,
10,
0,
"MODEL"
],
[
17,
10,
0,
1,
0,
"MODEL"
],
[
31,
1,
0,
25,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
{
"last_node_id": 35,
"last_link_id": 44,
"nodes": [
{
"id": 3,
"type": "LoadImage",
"pos": [
200,
1080
],
"size": [
210,
320
],
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
36
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download.jpg",
"image"
]
},
{
"id": 28,
"type": "LoadImage",
"pos": [
200,
1440
],
"size": [
210,
300
],
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
37
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"u=1909748437,3206566783&fm=253&fmt=auto&app=120&f=JPEG.webp",
"image"
]
},
{
"id": 31,
"type": "ImageBatch",
"pos": [
420,
1080
],
"size": {
"0": 210,
"1": 46
},
"flags": {
"collapsed": true
},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "image1",
"type": "IMAGE",
"link": 36
},
{
"name": "image2",
"type": "IMAGE",
"link": 37
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
38
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageBatch"
}
},
{
"id": 32,
"type": "ImageBatch",
"pos": [
420,
1120
],
"size": {
"0": 210,
"1": 46
},
"flags": {
"collapsed": true
},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "image1",
"type": "IMAGE",
"link": 38
},
{
"name": "image2",
"type": "IMAGE",
"link": 39
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
40
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageBatch"
}
},
{
"id": 33,
"type": "ImageBatch",
"pos": [
420,
1160
],
"size": {
"0": 210,
"1": 46
},
"flags": {
"collapsed": true
},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "image1",
"type": "IMAGE",
"link": 40
},
{
"name": "image2",
"type": "IMAGE",
"link": 41
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
42
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageBatch"
}
},
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
420,
1200
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 42
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"path/to/images",
"direct_Input"
]
},
{
"id": 27,
"type": "PortraitMaster_中文版",
"pos": [
420,
1330
],
"size": [
320,
1150
],
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "positive",
"type": "STRING",
"links": [
32
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative",
"type": "STRING",
"links": [
33
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "PortraitMaster_中文版"
},
"widgets_values": [
"肩部以上肖像",
1.5,
"女性",
20,
"中国人",
"-",
0.5,
"-",
0,
"-",
"棕色",
"开心",
1.5,
"椭圆形",
1,
0.2,
"法式波波头",
"黑色",
1,
"-",
0.5,
0.3,
0.41000000000000003,
0,
0,
0,
0,
0,
0,
1.2,
1.2,
1.2,
1.2,
"摄影棚灯光",
"从左侧",
1.2,
"disable",
"img, raw photo, (realistic:1.5)",
"(white background:1.5)",
"",
""
]
},
{
"id": 6,
"type": "PhotoMakerAdapter_Loader_fromhub",
"pos": [
760,
1330
],
"size": [
320,
80
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 6
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
14
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_fromhub"
},
"widgets_values": [
"TencentARC/PhotoMaker",
"photomaker-v1.bin"
]
},
{
"id": 5,
"type": "BaseModel_Loader_fromhub",
"pos": [
760,
1200
],
"size": [
320,
80
],
"flags": {},
"order": 3,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
6
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_fromhub"
},
"widgets_values": [
"SG161222/RealVisXL_V3.0"
]
},
{
"id": 10,
"type": "LoRALoader",
"pos": [
760,
1460
],
"size": [
320,
90
],
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 14
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
17
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LoRALoader"
},
"widgets_values": [
"xl_more_art-full.safetensors",
0.7000000000000001
]
},
{
"id": 26,
"type": "SDXLPromptStyler",
"pos": [
760,
1600
],
"size": [
320,
133.9999656677246
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "text_positive",
"type": "STRING",
"link": 32,
"widget": {
"name": "text_positive"
}
},
{
"name": "text_negative",
"type": "STRING",
"link": 33,
"widget": {
"name": "text_negative"
}
}
],
"outputs": [
{
"name": "positive_prompt_text_g",
"type": "STRING",
"links": [
34,
43
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative_prompt_text_g",
"type": "STRING",
"links": [
35,
44
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "SDXLPromptStyler"
},
"widgets_values": [
"",
"",
"广告-时尚编辑",
"No"
]
},
{
"id": 34,
"type": "DisplayText_Zho",
"pos": [
760,
1780
],
"size": [
320,
210
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "text",
"type": "STRING",
"link": 43,
"widget": {
"name": "text"
}
}
],
"outputs": [
{
"name": "text",
"type": "STRING",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "DisplayText_Zho"
},
"widgets_values": [
"",
"Fashion editorial style img, raw photo, (realistic:1.5), (head and shoulders portrait:1.5), (chinese woman 20-years-old:1.5), (brown eyes:1.25), (happy, happy expression:1.5), (oval shape face:1.0), (french bob hairstyle:1.25), (black hair:1.25), (disheveled:1.0), (white background:1.5), (skin details, skin texture:0.5), (skin pores:0.3), (dimples:0.41), (eyes details:1.2), (iris details:1.2), (circular iris:1.2), (circular pupil:1.2), (facial asymmetry, face asymmetry:0.2), (studio lighting from left:1.2) . High fashion, trendy, stylish, editorial, magazine style, professional, highly detailed"
]
},
{
"id": 1,
"type": "NEW_PhotoMaker_Generation",
"pos": [
760,
2180
],
"size": [
320,
300
],
"flags": {},
"order": 15,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 17
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 5,
"slot_index": 1
},
{
"name": "positive",
"type": "STRING",
"link": 34,
"widget": {
"name": "positive"
}
},
{
"name": "negative",
"type": "STRING",
"link": 35,
"widget": {
"name": "negative"
}
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
31
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "NEW_PhotoMaker_Generation"
},
"widgets_values": [
"",
"",
4,
20,
50,
5,
1024,
1024,
0,
"fixed"
]
},
{
"id": 35,
"type": "DisplayText_Zho",
"pos": [
760,
2040
],
"size": [
320,
90
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "text",
"type": "STRING",
"link": 44,
"widget": {
"name": "text"
}
}
],
"outputs": [
{
"name": "text",
"type": "STRING",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "DisplayText_Zho"
},
"widgets_values": [
"",
"outdated, blurry, noisy, unattractive, sloppy"
]
},
{
"id": 30,
"type": "LoadImage",
"pos": [
190,
2160
],
"size": [
220,
310
],
"flags": {},
"order": 4,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
41
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"u=1277628484,1988235544&fm=253&fmt=auto&app=138&f=JPEG.webp",
"image"
]
},
{
"id": 29,
"type": "LoadImage",
"pos": [
190,
1780
],
"size": [
220,
340
],
"flags": {},
"order": 5,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
39
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"u=425589426,3799949985&fm=253&fmt=auto&app=138&f=JPEG.webp",
"image"
]
},
{
"id": 25,
"type": "PreviewImage",
"pos": [
1100,
1200
],
"size": [
1260,
1280
],
"flags": {},
"order": 16,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 31
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
}
],
"links": [
[
5,
4,
0,
1,
1,
"IMAGE"
],
[
6,
5,
0,
6,
0,
"MODEL"
],
[
14,
6,
0,
10,
0,
"MODEL"
],
[
17,
10,
0,
1,
0,
"MODEL"
],
[
31,
1,
0,
25,
0,
"IMAGE"
],
[
32,
27,
0,
26,
0,
"STRING"
],
[
33,
27,
1,
26,
1,
"STRING"
],
[
34,
26,
0,
1,
2,
"STRING"
],
[
35,
26,
1,
1,
3,
"STRING"
],
[
36,
3,
0,
31,
0,
"IMAGE"
],
[
37,
28,
0,
31,
1,
"IMAGE"
],
[
38,
31,
0,
32,
0,
"IMAGE"
],
[
39,
29,
0,
32,
1,
"IMAGE"
],
[
40,
32,
0,
33,
0,
"IMAGE"
],
[
41,
30,
0,
33,
1,
"IMAGE"
],
[
42,
33,
0,
4,
0,
"IMAGE"
],
[
43,
26,
0,
34,
0,
"STRING"
],
[
44,
26,
1,
35,
0,
"STRING"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
{
"last_node_id": 25,
"last_link_id": 33,
"nodes": [
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
610,
420
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 4
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"path/to/images",
"direct_Input"
]
},
{
"id": 5,
"type": "BaseModel_Loader_fromhub",
"pos": [
270,
290
],
"size": {
"0": 320,
"1": 60
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
6
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_fromhub"
},
"widgets_values": [
"SG161222/RealVisXL_V3.0"
]
},
{
"id": 3,
"type": "LoadImage",
"pos": [
270,
400
],
"size": {
"0": 320,
"1": 440
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download.jpg",
"image"
]
},
{
"id": 6,
"type": "PhotoMakerAdapter_Loader_fromhub",
"pos": [
610,
290
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 6
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
33
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_fromhub"
},
"widgets_values": [
"TencentARC/PhotoMaker",
"photomaker-v1.bin"
]
},
{
"id": 2,
"type": "Prompt_Styler",
"pos": [
610,
550
],
"size": [
320,
180
],
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "positive_prompt",
"type": "STRING",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative_prompt",
"type": "STRING",
"links": [
2
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "Prompt_Styler"
},
"widgets_values": [
"a woman img, retro futurism, retro game",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Photographic (Default)"
]
},
{
"id": 1,
"type": "NEW_PhotoMaker_Generation",
"pos": [
610,
780
],
"size": [
320,
290
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 33
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 5,
"slot_index": 1
},
{
"name": "positive",
"type": "STRING",
"link": 1,
"widget": {
"name": "positive"
}
},
{
"name": "negative",
"type": "STRING",
"link": 2,
"widget": {
"name": "negative"
}
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
31
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "NEW_PhotoMaker_Generation"
},
"widgets_values": [
"",
"",
1,
20,
50,
5,
1024,
1024,
0,
"fixed"
]
},
{
"id": 25,
"type": "PreviewImage",
"pos": [
950,
290
],
"size": [
610,
780
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 31
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
}
],
"links": [
[
1,
2,
0,
1,
2,
"STRING"
],
[
2,
2,
1,
1,
3,
"STRING"
],
[
4,
3,
0,
4,
0,
"IMAGE"
],
[
5,
4,
0,
1,
1,
"IMAGE"
],
[
6,
5,
0,
6,
0,
"MODEL"
],
[
31,
1,
0,
25,
0,
"IMAGE"
],
[
33,
6,
0,
1,
0,
"MODEL"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
{
"last_node_id": 27,
"last_link_id": 35,
"nodes": [
{
"id": 4,
"type": "Ref_Image_Preprocessing",
"pos": [
610,
420
],
"size": {
"0": 320,
"1": 82
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "ref_image",
"type": "IMAGE",
"link": 4
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
5
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "Ref_Image_Preprocessing"
},
"widgets_values": [
"path/to/images",
"direct_Input"
]
},
{
"id": 3,
"type": "LoadImage",
"pos": [
270,
400
],
"size": {
"0": 320,
"1": 440
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"download.jpg",
"image"
]
},
{
"id": 2,
"type": "Prompt_Styler",
"pos": [
610,
550
],
"size": [
320,
180
],
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "positive_prompt",
"type": "STRING",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "negative_prompt",
"type": "STRING",
"links": [
2
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "Prompt_Styler"
},
"widgets_values": [
"a woman img, retro futurism, retro game",
"asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth",
"Photographic (Default)"
]
},
{
"id": 1,
"type": "NEW_PhotoMaker_Generation",
"pos": [
610,
780
],
"size": [
320,
290
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 35
},
{
"name": "pil_image",
"type": "IMAGE",
"link": 5,
"slot_index": 1
},
{
"name": "positive",
"type": "STRING",
"link": 1,
"widget": {
"name": "positive"
}
},
{
"name": "negative",
"type": "STRING",
"link": 2,
"widget": {
"name": "negative"
}
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
31
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "NEW_PhotoMaker_Generation"
},
"widgets_values": [
"",
"",
1,
20,
50,
5,
1024,
1024,
0,
"fixed"
]
},
{
"id": 25,
"type": "PreviewImage",
"pos": [
950,
290
],
"size": [
610,
780
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 31
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 27,
"type": "PhotoMakerAdapter_Loader_local",
"pos": [
610,
290
],
"size": [
320,
80
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "pipe",
"type": "MODEL",
"link": 34
}
],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
35
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PhotoMakerAdapter_Loader_local"
},
"widgets_values": [
"ComfyUI/",
"photomaker-v1.bin"
]
},
{
"id": 26,
"type": "BaseModel_Loader_local",
"pos": [
270,
290
],
"size": [
320,
60
],
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "pipe",
"type": "MODEL",
"links": [
34
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "BaseModel_Loader_local"
},
"widgets_values": [
null
]
}
],
"links": [
[
1,
2,
0,
1,
2,
"STRING"
],
[
2,
2,
1,
1,
3,
"STRING"
],
[
4,
3,
0,
4,
0,
"IMAGE"
],
[
5,
4,
0,
1,
1,
"IMAGE"
],
[
31,
1,
0,
25,
0,
"IMAGE"
],
[
34,
26,
0,
27,
0,
"MODEL"
],
[
35,
27,
0,
1,
0,
"MODEL"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}
\ No newline at end of file
import torch
import time
import os
import folder_paths
from diffusers.utils import load_image
from diffusers import EulerDiscreteScheduler
from .pipeline import PhotoMakerStableDiffusionXLPipeline
from huggingface_hub import hf_hub_download
from .style_template import styles
from PIL import Image
import numpy as np
# global variable
#photomaker_path = hf_hub_download(repo_id="TencentARC/PhotoMaker", filename="photomaker-v1.bin", repo_type="model")
device = "cuda" if torch.cuda.is_available() else "cpu"
STYLE_NAMES = list(styles.keys())
DEFAULT_STYLE_NAME = "Photographic (Default)"
def apply_style(style_name: str, positive: str, negative: str = "") -> tuple[str, str]:
p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME])
return p.replace("{prompt}", positive), n + ' ' + negative
class BaseModelLoader_fromhub_Node_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"base_model_path": ("STRING", {"default": "SG161222/RealVisXL_V3.0"})
}
}
RETURN_TYPES = ("MODEL",)
RETURN_NAMES = ("pipe",)
FUNCTION = "load_model"
CATEGORY = "📷PhotoMaker"
def load_model(self, base_model_path):
# Code to load the base model
pipe = PhotoMakerStableDiffusionXLPipeline.from_pretrained(
base_model_path,
torch_dtype=torch.float16,
use_safetensors=True,
variant="fp16"
).to(device)
return [pipe]
class BaseModelLoader_local_Node_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"ckpt_name": (folder_paths.get_filename_list("checkpoints"), )
}
}
RETURN_TYPES = ("MODEL",)
RETURN_NAMES = ("pipe",)
FUNCTION = "load_model"
CATEGORY = "📷PhotoMaker"
def load_model(self, ckpt_name):
# Code to load the base model
if not ckpt_name:
raise ValueError("Please provide the ckpt_name parameter with the name of the checkpoint file.")
ckpt_path = folder_paths.get_full_path("checkpoints", ckpt_name)
if not os.path.exists(ckpt_path):
raise FileNotFoundError(f"Checkpoint file {ckpt_path} not found.")
pipe = PhotoMakerStableDiffusionXLPipeline.from_single_file(
pretrained_model_link_or_path=ckpt_path,
torch_dtype=torch.float16,
use_safetensors=True,
variant="fp16"
).to(device)
return [pipe]
class PhotoMakerAdapterLoader_fromhub_Node_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"repo_id": ("STRING", {"default": "TencentARC/PhotoMaker"}),
"filename": ("STRING", {"default": "photomaker-v1.bin"}),
"pipe": ("MODEL",)
}
}
RETURN_TYPES = ("MODEL",)
FUNCTION = "load_photomaker_adapter"
CATEGORY = "📷PhotoMaker"
def load_photomaker_adapter(self, repo_id, filename, pipe):
# 使用hf_hub_download方法获取PhotoMaker文件的路径
photomaker_path = hf_hub_download(
repo_id = repo_id,
filename = filename,
repo_type="model"
)
# 加载PhotoMaker检查点
pipe.load_photomaker_adapter(
os.path.dirname(photomaker_path),
subfolder="",
weight_name=os.path.basename(photomaker_path),
trigger_word="img"
)
pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)
return [pipe]
class PhotoMakerAdapterLoader_local_Node_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"pm_model_path": ("STRING", {"default": "enter your photomaker model path"}),
"filename": ("STRING", {"default": "photomaker-v1.bin"}),
"pipe": ("MODEL",)
}
}
RETURN_TYPES = ("MODEL",)
FUNCTION = "load_photomaker_adapter"
CATEGORY = "📷PhotoMaker"
def load_photomaker_adapter(self, pm_model_path, filename, pipe):
# 拼接完整的模型路径
photomaker_path = os.path.join(pm_model_path, filename)
# 加载PhotoMaker检查点
pipe.load_photomaker_adapter(
os.path.dirname(photomaker_path),
subfolder="",
weight_name=os.path.basename(photomaker_path),
trigger_word="img"
)
pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)
return [pipe]
class LoRALoader_Node_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"lora_name": (folder_paths.get_filename_list("loras"), ),
"lora_weight": ("FLOAT", {"default": 0.5, "min": 0, "max": 1.0, "display": "slider"}),
"pipe": ("MODEL",)
}
}
RETURN_TYPES = ("MODEL",)
FUNCTION = "load_lora"
CATEGORY = "📷PhotoMaker"
def load_lora(self, lora_name, lora_weight, pipe):
lora_path = folder_paths.get_full_path("loras", lora_name)
lora_name_processed = os.path.basename(lora_path).replace(".safetensors", "")
# 解融合之前的 LoRA
pipe.unfuse_lora()
# 卸载之前加载的 LoRA 权重
pipe.unload_lora_weights()
# 重新加载新的 LoRA 权重
unique_adapter_name = f"photomaker_{int(time.time())}"
pipe.load_lora_weights(os.path.dirname(lora_path), weight_name=os.path.basename(lora_path), adapter_name=unique_adapter_name)
# 设置适配器和权重
adapter_weights = [1.0, lora_weight]
pipe.set_adapters(["photomaker", unique_adapter_name], adapter_weights=adapter_weights)
# 融合 LoRA
pipe.fuse_lora()
return [pipe]
class ImagePreprocessingNode_Zho:
def __init__(self, ref_image=None, ref_images_path=None, mode="direct_Input"):
self.ref_image = ref_image
self.ref_images_path = ref_images_path
self.mode = mode
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"ref_images_path": ("STRING", {"default": "path/to/images"}), # 图像文件夹路径
"mode": (["direct_Input", "path_Input"], {"default": "direct_Input"}) # 选择模式
},
"optional": {
"ref_image": ("IMAGE",) # 直接输入图像(可选)
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "preprocess_image"
CATEGORY = "📷PhotoMaker"
def preprocess_image(self, ref_image=None, ref_images_path=None, mode="direct_Input"):
# 使用传入的参数更新类属性
ref_image = ref_image if ref_image is not None else ref_image
ref_images_path = ref_images_path if ref_images_path is not None else ref_images_path
mode = mode
if mode == "direct_Input" and ref_image is not None:
# 直接图像处理
pil_images = []
for image in ref_image:
image_np = (255. * image.cpu().numpy().squeeze()).clip(0, 255).astype(np.uint8)
pil_image = Image.fromarray(image_np)
pil_images.append(pil_image)
return pil_images
elif mode == "path_Input":
# 路径输入图像
image_basename_list = os.listdir(ref_images_path)
image_path_list = [
os.path.join(ref_images_path, basename)
for basename in image_basename_list
if not basename.startswith('.') and basename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.webp'))
]
return [load_image(image_path) for image_path in image_path_list]
else:
raise ValueError("Invalid mode. Choose 'direct_Input' or 'path_Input'.")
'''
class CompositeImageGenerationNode_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"prompt": ("STRING", {"default": "sci-fi, closeup portrait photo of a man img wearing the sunglasses in Iron man suit, face, slim body, high quality, film grain", "multiline": True}),
"negative_prompt": ("STRING", {"default": "asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth", "multiline": True}),
"style_name": (STYLE_NAMES, {"default": DEFAULT_STYLE_NAME}),
"style_strength_ratio": ("INT", {"default": 20, "min": 1, "max": 50, "display": "slider"}),
"steps": ("INT", {"default": 50, "min": 1, "max": 100, "step": 1, "display": "slider"}),
"guidance_scale": ("FLOAT", {"default": 5, "min": 0, "max": 10}),
"batch_size": ("INT", {"default": 1, "min": 1, "max": 4}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"width": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 32, "display": "slider"}),
"height": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 32, "display": "slider"}),
"pipe": ("MODEL",),
"pil_image": ("IMAGE",)
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "generate_image"
CATEGORY = "📷PhotoMaker"
def generate_image(self, style_name, style_strength_ratio, steps, seed, prompt, negative_prompt, guidance_scale, batch_size, pil_image, pipe, width, height):
# Code for the remaining process including style template application, merge step calculation, etc.
prompt, negative_prompt = apply_style(style_name, prompt, negative_prompt)
start_merge_step = int(float(style_strength_ratio) / 100 * steps)
if start_merge_step > 30:
start_merge_step = 30
generator = torch.Generator(device=device).manual_seed(seed)
output = pipe(
prompt=prompt,
input_id_images=[pil_image],
negative_prompt=negative_prompt,
num_images_per_prompt=batch_size,
num_inference_steps=steps,
start_merge_step=start_merge_step,
generator=generator,
guidance_scale=guidance_scale,
width=width,
height=height,
return_dict=False
)
# 检查输出类型并相应处理
if isinstance(output, tuple):
# 当返回的是元组时,第一个元素是图像列表
images_list = output[0]
else:
# 如果返回的是 StableDiffusionXLPipelineOutput,需要从中提取图像
images_list = output.images
# 转换图像为 torch.Tensor,并调整维度顺序为 NHWC
images_tensors = []
for img in images_list:
# 将 PIL.Image 转换为 numpy.ndarray
img_array = np.array(img)
# 转换 numpy.ndarray 为 torch.Tensor
img_tensor = torch.from_numpy(img_array).float() / 255.
# 转换图像格式为 CHW (如果需要)
if img_tensor.ndim == 3 and img_tensor.shape[-1] == 3:
img_tensor = img_tensor.permute(2, 0, 1)
# 添加批次维度并转换为 NHWC
img_tensor = img_tensor.unsqueeze(0).permute(0, 2, 3, 1)
images_tensors.append(img_tensor)
if len(images_tensors) > 1:
output_image = torch.cat(images_tensors, dim=0)
else:
output_image = images_tensors[0]
return (output_image,)
'''
#拆分生成块
class Prompt_Style_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"prompt": ("STRING", {"default": "sci-fi, closeup portrait photo of a man img wearing the sunglasses in Iron man suit, face, slim body, high quality, film grain", "multiline": True}),
"negative_prompt": ("STRING", {"default": "asymmetry, worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), open mouth", "multiline": True}),
"style_name": (STYLE_NAMES, {"default": DEFAULT_STYLE_NAME})
}
}
RETURN_TYPES = ('STRING','STRING',)
RETURN_NAMES = ('positive_prompt','negative_prompt',)
FUNCTION = "prompt_style"
CATEGORY = "📷PhotoMaker"
def prompt_style(self, style_name, prompt, negative_prompt):
prompt, negative_prompt = apply_style(style_name, prompt, negative_prompt)
return prompt, negative_prompt
class NEWCompositeImageGenerationNode_Zho:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"positive": ("STRING", {"multiline": True, "forceInput": True}),
"negative": ("STRING", {"multiline": True, "forceInput": True}),
"batch_size": ("INT", {"default": 1, "min": 1, "max": 4, "display": "slider"}),
"style_strength_ratio": ("INT", {"default": 20, "min": 1, "max": 50, "display": "slider"}),
"steps": ("INT", {"default": 50, "min": 1, "max": 100, "step": 1, "display": "slider"}),
"guidance_scale": ("FLOAT", {"default": 5, "min": 0, "max": 10, "display": "slider"}),
"width": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 32, "display": "slider"}),
"height": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 32, "display": "slider"}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"pipe": ("MODEL",),
"pil_image": ("IMAGE",)
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "generate_image"
CATEGORY = "📷PhotoMaker"
def generate_image(self, steps, seed, positive, negative, style_strength_ratio, guidance_scale, batch_size, pil_image, pipe, width, height):
# Code for the remaining process including style template application, merge step calculation, etc.
start_merge_step = int(float(style_strength_ratio) / 100 * steps)
if start_merge_step > 30:
start_merge_step = 30
generator = torch.Generator(device=device).manual_seed(seed)
output = pipe(
prompt=positive,
input_id_images=[pil_image],
negative_prompt=negative,
num_images_per_prompt=batch_size,
num_inference_steps=steps,
start_merge_step=start_merge_step,
generator=generator,
guidance_scale=guidance_scale,
width=width,
height=height,
return_dict=False
)
# 检查输出类型并相应处理
if isinstance(output, tuple):
# 当返回的是元组时,第一个元素是图像列表
images_list = output[0]
else:
# 如果返回的是 StableDiffusionXLPipelineOutput,需要从中提取图像
images_list = output.images
# 转换图像为 torch.Tensor,并调整维度顺序为 NHWC
images_tensors = []
for img in images_list:
# 将 PIL.Image 转换为 numpy.ndarray
img_array = np.array(img)
# 转换 numpy.ndarray 为 torch.Tensor
img_tensor = torch.from_numpy(img_array).float() / 255.
# 转换图像格式为 CHW (如果需要)
if img_tensor.ndim == 3 and img_tensor.shape[-1] == 3:
img_tensor = img_tensor.permute(2, 0, 1)
# 添加批次维度并转换为 NHWC
img_tensor = img_tensor.unsqueeze(0).permute(0, 2, 3, 1)
images_tensors.append(img_tensor)
if len(images_tensors) > 1:
output_image = torch.cat(images_tensors, dim=0)
else:
output_image = images_tensors[0]
return (output_image,)
NODE_CLASS_MAPPINGS = {
"BaseModel_Loader_fromhub": BaseModelLoader_fromhub_Node_Zho,
"BaseModel_Loader_local": BaseModelLoader_local_Node_Zho,
"PhotoMakerAdapter_Loader_fromhub": PhotoMakerAdapterLoader_fromhub_Node_Zho,
"PhotoMakerAdapter_Loader_local": PhotoMakerAdapterLoader_local_Node_Zho,
"LoRALoader": LoRALoader_Node_Zho,
"Ref_Image_Preprocessing": ImagePreprocessingNode_Zho,
"Prompt_Styler": Prompt_Style_Zho,
"NEW_PhotoMaker_Generation": NEWCompositeImageGenerationNode_Zho,
#"PhotoMaker_Generation": CompositeImageGenerationNode_Zho
}
NODE_DISPLAY_NAME_MAPPINGS = {
"BaseModel_Loader_fromhub": "📷Base Model Loader from hub🤗",
"BaseModel_Loader_local": "📷Base Model Loader locally",
"PhotoMakerAdapter_Loader_fromhub": "📷PhotoMaker Adapter Loader from hub🤗",
"PhotoMakerAdapter_Loader_local": "📷PhotoMaker Adapter Loader locally",
"LoRALoader": "📷LoRALoader",
"Ref_Image_Preprocessing": "📷Ref Image Preprocessing",
"Prompt_Styler": "📷Prompt_Styler",
"NEW_PhotoMaker_Generation": "📷NEW PhotoMaker Generation",
#"PhotoMaker_Generation": "📷PhotoMaker Generation"
}
![PNSTYLE_23png](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/15f9ebaf-b205-4cbd-928e-eca1a0cacb7f)
# ComfyUI PhotoMaker
Unofficial implementation of [PhotoMaker](https://github.com/TencentARC/PhotoMaker) for ComfyUI
<!---
![Dingtalk_20240117150313](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/da664c2b-cb30-44e2-85ec-d6070fcfa8f0)
![Dingtalk_20240117161736](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/07c924ab-3ee5-4919-87bc-ac49c28914f1)
--->
![Dingtalk_20240118163802](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/0292bf55-21b7-4025-bc27-7e3e7ccc2af3)
<!---
![Dingtalk_20240118163953](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/9b8a665f-6c9c-441c-aa81-fc56423de89e)
--->
单张参考与多张参考的对比:
![Dingtalk_20240117201650](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/e7bccd61-7855-46c2-a6bc-31b34e742927)
![Dingtalk_20240117201201](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/6bbcfcf9-9027-4c6f-9be1-750971b7848c)
## 项目介绍 | Info
- 来自对[PhotoMaker](https://github.com/TencentARC/PhotoMaker)的非官方实现
- 版本:V2.5 支持lora、支持多批次、支持通用的styler
<!---
节点拆分 + 支持本地模型 + 支持自定义尺寸 +提速3倍 + 支持多图直接输入
--->
![Dingtalk_20240119194547](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/d067fc21-3b51-44bc-b76e-9351a7f6966a)
## 视频演示
<!---
https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/8718a70e-a5d7-463b-b36e-de1ffefad9ed
--->
https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/d58af6e7-d0f3-41ff-ab33-195cb6d66e9e
## 节点说明 | Features
- 基础模型加载 | base model loader
- 📷Base Model Loader from hub🤗:支持从 huggingface hub 自动下载模型,输入模型名称(如:SG161222/RealVisXL_V3.0)即可
- 📷Base Model Loader locally:支持加载本地模型(需 SDXL 系列模型)
- PhotoMaker Adapter 模型加载 | PhotoMaker Adapter Loader
- 📷PhotoMaker Adapter Loader from hub🤗:支持从 huggingface hub 自动下载模型
- 📷PhotoMaker Adapter Loader locally:支持加载本地模型,输入 photomaker-v1.bin 模型所在路径即可
- 参考图预处理 | 📷Ref Image Preprocessing
- 直接模式 | Direct_input:接入单/多张图像(非必要项)
- 路径模式 | Path_input:自动读取路径中的所有图像
- Lora模型加载 | 📷LoRALoader 🆕
- 支持加载本地 lora 模型
- 支持权重调节
- 提示词 + 风格 | 📷Prompt_Styler 🆕
- 与各种提示词(文本)输入(如肖像大师等)、styler兼容
- prompt、negative:正负提示词
- 支持权重调节
- style_name:支持官方提供的10种风格
- (No style)
- Cinematic
- Disney Charactor
- Digital Art
- Photographic (Default)
- Fantasy art
- Neonpunk
- Enhance
- Comic book
- Lowpoly
- Line art
- PhotoMaker 生成 | 📷PhotoMaker Generation 🆕
- pipe:接入模型
- pil_image:接入预处理图像
- positivet、negative:正负提示词
- batch_size:生成数量
- style_strength_ratio:风格混合强度(高于30按30计算)
- step:步数,官方默认50步,但毕竟是基于SDXL模型,我实测下来30步足够了
- guidance_scale:提示词相关度,一般默认为5
- width、height:尺寸设置(需1024维度)
- seed:种子
<!---
- base_model_path:支持输入huggingface模型名称自动下载模型(如:SG161222/RealVisXL_V3.0)
- ref_images_path:支持批量读取参考图像,放入文件夹中即可
- ptompt、negative:正负提示词
- style_name:支持官方提供的10种风格
- (No style)
- Cinematic
- Disney Charactor
- Digital Art
- Photographic (Default)
- Fantasy art
- Neonpunk
- Enhance
- Comic book
- Lowpoly
- Line art
- style_strength_ratio:风格混合强度(高于30按30计算)
- step:步数,官方默认50步,但毕竟是基于SDXL模型,我实测下来30步足够了
- guidance_scale:提示词相关度,一般默认为5
- seed:种子
--->
## 风格 | Styles
![PNSTYLE_2](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/dc675478-47a0-456d-946b-0cf781aa4c28)
## 安装 | Install
<!---
- 推荐使用管理器 ComfyUI Manager 安装
--->
- 手动安装:
1. `cd custom_nodes`
2. `git clone https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker.git`
3. `cd custom_nodes/ComfyUI-PhotoMaker`
4. `pip install -r requirements.txt`
5. 重启 ComfyUI
## 工作流 | Workflows
- [V2.5 Disney-Character_PhotoMaker + DragNUWA](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/Disney-Character_PhotoMaker%2BDragNUW%E3%80%90Zho%E3%80%91.json) 🆕
https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/ca2bfff4-701c-4960-ac11-b893f90c044c
- [V2.5 lora + batch](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/PhotoMaker_lora_batch%E3%80%90Zho%E3%80%91.json) 🆕
![Dingtalk_20240119202403](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/b862b89f-1609-43d9-84a1-5f11a2d1ab2d)
- [V2.5 portraitmaster + styler + lora](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/PhotoMaker_lora_portrait_styler%E3%80%90Zho%E3%80%91.json) 🆕
![Dingtalk_20240119201125](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/38e01035-139e-4a89-8982-6f7168684045)
- [V2.5 本地模型 locally](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/V2.5%20PhotoMaker_locally%E3%80%90Zho%E3%80%91.json)
- [V2.5 自动下载 huggingface hub](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/V2.5%20PhotoMaker_fromhub%E3%80%90Zho%E3%80%91.json)
(注:特意补充了 V2.5 的基础工作流,V2.0 工作流已弃用)
<!---
- [V2.0 本地模型 locally](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/PhotoMaker_locally%E3%80%90Zho%E3%80%91.json)
![QQ截图20240118163432](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/bf6a55ae-767e-4aaf-9f75-6f752bb5b530)
- [V2.0 自动下载 huggingface hub](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/blob/main/PhotoMaker%20Workflows/PhotoMaker_fromhub%E3%80%90Zho%E3%80%91.json)
![QQ截图20240118163252](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/f645c1b7-2548-45fc-b388-0ebe62e2724d)
--->
## 更新日志
- 20240122
新增 Disney-Character: PhotoMaker + DragNUWA 工作流,可配合 DragNUWA 融合多个人物特征生成迪士尼风格大片!
- 20240121
修复 bfloat16 bug
- 20240120
补充两个基础工作流
- 20240119
更新为 V2.5:支持lora、支持自定义生成数量、支持通用提示词输入(文本)如:styler、portraitmater等
新增 lora + batch、portraitmaster + styler + lora 两个工作流
- 20240119
更新为 V2.1:参考图改为直接输入/路径输入两种新模式,其中直接输入支持多图
![Dingtalk_20240119022341](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/78595f2c-7f87-477a-9896-007dd24fe8c9)
- 20240118
更新为 V2.0:节点拆分 + 支持本地模型 + 支持自定义尺寸 +提速3倍
新增本地、hub加载工作流
- 20240117
新增单张图输入,并给出对比图
修复bug,初版上线
- 20240116
创建项目
## 速度实测 | Speed
- V2.0 提速 3 倍
- A100 50步 7s
![image](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/4ae13ffc-c770-4551-bcb2-ce0b0ddc1367)
- V1.5
- A100 50步 23s
![image](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/df6eacda-2640-425b-b5ca-1ab5a8a61a66)
- v100 50步 90s
![image](https://github.com/ZHO-ZHO-ZHO/ComfyUI-PhotoMaker/assets/140084057/973b8b6b-9195-4044-b75d-bd833bd6421e)
## Stars
[![Star History Chart](https://api.star-history.com/svg?repos=ZHO-ZHO-ZHO/ComfyUI-PhotoMaker&type=Date)](https://star-history.com/#ZHO-ZHO-ZHO/ComfyUI-PhotoMaker&Date)
## 关于我 | About me
📬 **联系我**
- 邮箱:zhozho3965@gmail.com
- QQ 群:839821928
🔗 **社交媒体**
- 个人页:[-Zho-](https://jike.city/zho)
- Bilibili:[我的B站主页](https://space.bilibili.com/484366804)
- X(Twitter):[我的Twitter](https://twitter.com/ZHOZHO672070)
- 小红书:[我的小红书主页](https://www.xiaohongshu.com/user/profile/63f11530000000001001e0c8?xhsshare=CopyLink&appuid=63f11530000000001001e0c8&apptime=1690528872)
💡 **支持我**
- B站:[B站充电](https://space.bilibili.com/484366804)
- 爱发电:[为我充电](https://afdian.net/a/ZHOZHO)
## Credits
感谢[@erLin](https://twitter.com/eviljer)对ComfyUI 的图像张量 Shape (N, H, W, C)的提醒,帮助我成功修复了bug!
[PhotoMaker](https://github.com/TencentARC/PhotoMaker)
from .PhotoMakerNode import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
# Merge image encoder and fuse module to create an ID Encoder
# send multiple ID images, we can directly obtain the updated text encoder containing a stacked ID embedding
import torch
import torch.nn as nn
from transformers.models.clip.modeling_clip import CLIPVisionModelWithProjection
from transformers.models.clip.configuration_clip import CLIPVisionConfig
from transformers import PretrainedConfig
VISION_CONFIG_DICT = {
"hidden_size": 1024,
"intermediate_size": 4096,
"num_attention_heads": 16,
"num_hidden_layers": 24,
"patch_size": 14,
"projection_dim": 768
}
class MLP(nn.Module):
def __init__(self, in_dim, out_dim, hidden_dim, use_residual=True):
super().__init__()
if use_residual:
assert in_dim == out_dim
self.layernorm = nn.LayerNorm(in_dim)
self.fc1 = nn.Linear(in_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, out_dim)
self.use_residual = use_residual
self.act_fn = nn.GELU()
def forward(self, x):
residual = x
x = self.layernorm(x)
x = self.fc1(x)
x = self.act_fn(x)
x = self.fc2(x)
if self.use_residual:
x = x + residual
return x
class FuseModule(nn.Module):
def __init__(self, embed_dim):
super().__init__()
self.mlp1 = MLP(embed_dim * 2, embed_dim, embed_dim, use_residual=False)
self.mlp2 = MLP(embed_dim, embed_dim, embed_dim, use_residual=True)
self.layer_norm = nn.LayerNorm(embed_dim)
def fuse_fn(self, prompt_embeds, id_embeds):
stacked_id_embeds = torch.cat([prompt_embeds, id_embeds], dim=-1)
stacked_id_embeds = self.mlp1(stacked_id_embeds) + prompt_embeds
stacked_id_embeds = self.mlp2(stacked_id_embeds)
stacked_id_embeds = self.layer_norm(stacked_id_embeds)
return stacked_id_embeds
def forward(
self,
prompt_embeds,
id_embeds,
class_tokens_mask,
) -> torch.Tensor:
# id_embeds shape: [b, max_num_inputs, 1, 2048]
id_embeds = id_embeds.to(prompt_embeds.dtype)
num_inputs = class_tokens_mask.sum().unsqueeze(0) # TODO: check for training case
batch_size, max_num_inputs = id_embeds.shape[:2]
# seq_length: 77
seq_length = prompt_embeds.shape[1]
# flat_id_embeds shape: [b*max_num_inputs, 1, 2048]
flat_id_embeds = id_embeds.view(
-1, id_embeds.shape[-2], id_embeds.shape[-1]
)
# valid_id_mask [b*max_num_inputs]
valid_id_mask = (
torch.arange(max_num_inputs, device=flat_id_embeds.device)[None, :]
< num_inputs[:, None]
)
valid_id_embeds = flat_id_embeds[valid_id_mask.flatten()]
prompt_embeds = prompt_embeds.view(-1, prompt_embeds.shape[-1])
class_tokens_mask = class_tokens_mask.view(-1)
valid_id_embeds = valid_id_embeds.view(-1, valid_id_embeds.shape[-1])
# slice out the image token embeddings
image_token_embeds = prompt_embeds[class_tokens_mask]
stacked_id_embeds = self.fuse_fn(image_token_embeds, valid_id_embeds)
assert class_tokens_mask.sum() == stacked_id_embeds.shape[0], f"{class_tokens_mask.sum()} != {stacked_id_embeds.shape[0]}"
prompt_embeds.masked_scatter_(class_tokens_mask[:, None], stacked_id_embeds.to(prompt_embeds.dtype))
updated_prompt_embeds = prompt_embeds.view(batch_size, seq_length, -1)
return updated_prompt_embeds
class PhotoMakerIDEncoder(CLIPVisionModelWithProjection):
def __init__(self):
super().__init__(CLIPVisionConfig(**VISION_CONFIG_DICT))
self.visual_projection_2 = nn.Linear(1024, 1280, bias=False)
self.fuse_module = FuseModule(2048)
def forward(self, id_pixel_values, prompt_embeds, class_tokens_mask):
b, num_inputs, c, h, w = id_pixel_values.shape
id_pixel_values = id_pixel_values.view(b * num_inputs, c, h, w)
shared_id_embeds = self.vision_model(id_pixel_values)[1]
id_embeds = self.visual_projection(shared_id_embeds)
id_embeds_2 = self.visual_projection_2(shared_id_embeds)
id_embeds = id_embeds.view(b, num_inputs, 1, -1)
id_embeds_2 = id_embeds_2.view(b, num_inputs, 1, -1)
id_embeds = torch.cat((id_embeds, id_embeds_2), dim=-1)
updated_prompt_embeds = self.fuse_module(prompt_embeds, id_embeds, class_tokens_mask)
return updated_prompt_embeds
if __name__ == "__main__":
PhotoMakerIDEncoder()
This diff is collapsed.
diffusers==0.25.0
transformers==4.36.2
huggingface-hub==0.20.2
spaces==0.19.4
numpy
accelerate
safetensors
omegaconf
peft
style_list = [
{
"name": "(No style)",
"prompt": "{prompt}",
"negative_prompt": "",
},
{
"name": "Cinematic",
"prompt": "cinematic still {prompt} . emotional, harmonious, vignette, highly detailed, high budget, bokeh, cinemascope, moody, epic, gorgeous, film grain, grainy",
"negative_prompt": "anime, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured",
},
{
"name": "Disney Charactor",
"prompt": "A Pixar animation character of {prompt} . pixar-style, studio anime, Disney, high-quality",
"negative_prompt": "lowres, bad anatomy, bad hands, text, bad eyes, bad arms, bad legs, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, blurry, grayscale, noisy, sloppy, messy, grainy, highly detailed, ultra textured, photo",
},
{
"name": "Digital Art",
"prompt": "concept art {prompt} . digital artwork, illustrative, painterly, matte painting, highly detailed",
"negative_prompt": "photo, photorealistic, realism, ugly",
},
{
"name": "Photographic (Default)",
"prompt": "cinematic photo {prompt} . 35mm photograph, film, bokeh, professional, 4k, highly detailed",
"negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly",
},
{
"name": "Fantasy art",
"prompt": "ethereal fantasy concept art of {prompt} . magnificent, celestial, ethereal, painterly, epic, majestic, magical, fantasy art, cover art, dreamy",
"negative_prompt": "photographic, realistic, realism, 35mm film, dslr, cropped, frame, text, deformed, glitch, noise, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, sloppy, duplicate, mutated, black and white",
},
{
"name": "Neonpunk",
"prompt": "neonpunk style {prompt} . cyberpunk, vaporwave, neon, vibes, vibrant, stunningly beautiful, crisp, detailed, sleek, ultramodern, magenta highlights, dark purple shadows, high contrast, cinematic, ultra detailed, intricate, professional",
"negative_prompt": "painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured",
},
{
"name": "Enhance",
"prompt": "breathtaking {prompt} . award-winning, professional, highly detailed",
"negative_prompt": "ugly, deformed, noisy, blurry, distorted, grainy",
},
{
"name": "Comic book",
"prompt": "comic {prompt} . graphic illustration, comic art, graphic novel art, vibrant, highly detailed",
"negative_prompt": "photograph, deformed, glitch, noisy, realistic, stock photo",
},
{
"name": "Lowpoly",
"prompt": "low-poly style {prompt} . low-poly game art, polygon mesh, jagged, blocky, wireframe edges, centered composition",
"negative_prompt": "noisy, sloppy, messy, grainy, highly detailed, ultra textured, photo",
},
{
"name": "Line art",
"prompt": "line art drawing {prompt} . professional, sleek, modern, minimalist, graphic, line art, vector graphics",
"negative_prompt": "anime, photorealistic, 35mm film, deformed, glitch, blurry, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, mutated, realism, realistic, impressionism, expressionism, oil, acrylic",
}
]
styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
FROM image.sourcefind.cn:5000/gpu/admin/base/jupyterlab-pytorch:2.2.0-python3.10-cuda12.1-ubuntu22.04 as base
ARG IMAGE=comfyui-photomaker-zho
ARG IMAGE_UPPER=ComfyUI-PhotoMaker-ZHO
ARG BRANCH=gpu
RUN cd /root && \
git clone http://developer.hpccube.com/codes/chenpangpang/ComfyUI.git
RUN cd /root/ComfyUI && \
pip install -r requirements.txt
RUN cd /root && \
git clone -b $BRANCH http://developer.hpccube.com/codes/chenpangpang/$IMAGE.git
RUN mv /root/$IMAGE/$IMAGE_UPPER /root/ComfyUI/custom_nodes/$IMAGE_UPPER && \
cd /root/ComfyUI/custom_nodes/$IMAGE_UPPER && \
pip install -r requirements.txt
#########
# Prod #
#########
FROM image.sourcefind.cn:5000/gpu/admin/base/jupyterlab-pytorch:2.2.0-python3.10-cuda12.1-ubuntu22.04
ARG IMAGE=comfyui-photomaker-zho
ARG IMAGE_UPPER=ComfyUI-PhotoMaker-ZHO
COPY chenyh/$IMAGE/frpc_linux_amd64_v0.2 /opt/conda/lib/python3.10/site-packages/gradio/
RUN chmod +x /opt/conda/lib/python3.10/site-packages/gradio/frpc_linux_amd64_v0.2
#COPY chenyh/$IMAGE/coqui/XTTS-v2 /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2
COPY --from=base /opt/conda/lib/python3.10/site-packages /opt/conda/lib/python3.10/site-packages
COPY --from=base /root/ComfyUI /root/ComfyUI
COPY --from=base /root/$IMAGE/启动器.ipynb /root/$IMAGE/start.sh /root/
\ No newline at end of file
#!/bin/bash
cd ComfyUI
python main.py --listen
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment