Skip to content

Commit 2b5dfaf

Browse files
sync: update stable-diffusion.cpp submodule
1 parent df5c1ea commit 2b5dfaf

24 files changed

+309
-116
lines changed

README.md

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ output = stable_diffusion.txt_to_img(
195195
progress_callback=callback,
196196
# seed=1337, # Uncomment to set a specific seed
197197
)
198-
output[0].save("output.png") # Image returned as list of PIL Images
198+
output[0].save("output.png") # Output returned as list of PIL Images
199199
```
200200

201201
#### With LoRA (Stable Diffusion)
@@ -256,8 +256,8 @@ LoRAs can be used with FLUX models in the same way as Stable Diffusion models ([
256256

257257
Note that:
258258

259-
- It is recommended to use LoRA with naming formats compatible with ComfyUI.
260-
- Only the Flux-dev q8_0 will work with LoRAs.
259+
- It is recommended you use LoRAs with naming formats compatible with ComfyUI.
260+
- LoRAs will only work with Flux-dev q8_0.
261261
- You can download FLUX LoRA models from https://huggingface.co/XLabs-AI/flux-lora-collection/tree/main (you must use a comfy converted version!!!).
262262

263263
### SD3.5 Image Generation
@@ -287,9 +287,79 @@ output = stable_diffusion.txt_to_img(
287287
)
288288
```
289289

290+
### Image to Image
291+
292+
```python
293+
from stable_diffusion_cpp import StableDiffusion
294+
295+
INPUT_IMAGE = "../input.png"
296+
# INPUT_IMAGE = Image.open("../input.png") # or alternatively, pass as PIL Image
297+
298+
stable_diffusion = StableDiffusion(model_path="../models/v1-5-pruned-emaonly.safetensors")
299+
300+
output = stable_diffusion.img_to_img(
301+
prompt="blue eyes",
302+
image=INPUT_IMAGE,
303+
strength=0.4,
304+
)
305+
```
306+
307+
### PhotoMaker
308+
309+
You can use [PhotoMaker](https://github.com/TencentARC/PhotoMaker) to personalize generated images with your own ID.
310+
311+
**NOTE**, currently PhotoMaker **ONLY** works with **SDXL** (any SDXL model files will work).
312+
The VAE in SDXL encounters NaN issues. You can find a fixed VAE here: [SDXL VAE FP16 Fix](https://huggingface.co/madebyollin/sdxl-vae-fp16-fix/blob/main/sdxl_vae.safetensors).
313+
314+
Download PhotoMaker model file (in safetensor format) [here](https://huggingface.co/bssrdf/PhotoMaker). The official release of the model file (in .bin format) does not work with `stablediffusion.cpp`.
315+
316+
In prompt, make sure you have a class word followed by the trigger word `"img"` (hard-coded for now). The class word could be one of `"man, woman, girl, boy"`. If input ID images contain asian faces, add `Asian` before the class word.
317+
318+
```python
319+
from stable_diffusion_cpp import StableDiffusion
320+
321+
stable_diffusion = StableDiffusion(
322+
model_path="../models/sdxl.vae.safetensors",
323+
vae_path="../models/sdxl.vae.safetensors",
324+
stacked_id_embed_dir="../models/photomaker-v1.safetensors",
325+
# keep_vae_on_cpu=True, # If on low memory GPUs (<= 8GB), setting this to True is recommended to get artifact free images
326+
)
327+
328+
output = stable_diffusion.txt_to_img(
329+
cfg_scale=5.0, # a cfg_scale of 5.0 is recommended for PhotoMaker
330+
height=1024,
331+
width=1024,
332+
style_strength=10, # (0-100)% Default is 20 and 10-20 typically gets good results. Lower ratio means more faithfully following input ID (not necessarily better quality).
333+
sample_method="euler",
334+
prompt="a man img, retro futurism, retro game art style but extremely beautiful, intricate details, masterpiece, best quality, space-themed, cosmic, celestial, stars, galaxies, nebulas, planets, science fiction, highly detailed",
335+
negative_prompt="realistic, photo-realistic, worst quality, greyscale, bad anatomy, bad hands, error, text",
336+
input_id_images_path="../assets/newton_man",
337+
)
338+
```
339+
340+
### PhotoMaker Version 2
341+
342+
[PhotoMaker Version 2 (PMV2)](https://github.com/TencentARC/PhotoMaker/blob/main/README_pmv2.md) has some key improvements. Unfortunately it has a very heavy dependency which makes running it a bit involved in `SD.cpp`.
343+
344+
Running PMV2 Requires running a python script `face_detect.py` (found [here](https://github.com/leejet/stable-diffusion.cpp/blob/master/face_detect.py)) to obtain **id_embeds** for the given input images.
345+
346+
```
347+
python face_detect.py <input_image_dir>
348+
```
349+
350+
An `id_embeds.safetensors` file will be generated in `input_images_dir`.
351+
352+
**Note: this step is only needed to run once; the same `id_embeds` can be reused**
353+
354+
- Run the same command as in version 1 but replacing `photomaker-v1.safetensors` with `photomaker-v2.safetensors`.
355+
356+
You can download `photomaker-v2.safetensors` from [here](https://huggingface.co/bssrdf/PhotoMakerV2).
357+
358+
- All the other parameters from Version 1 remain the same for Version 2.
359+
290360
### Other High-level API Examples
291361

292-
Other examples for the high-level API (such as image to image, upscaling and model conversion) can be found in the [tests](tests) directory.
362+
Other examples for the high-level API (such as upscaling and model conversion) can be found in the [tests](tests) directory.
293363

294364
## Low-level API
295365

@@ -340,14 +410,6 @@ pip install -e .
340410

341411
Now you can make changes to the code within the `stable_diffusion_cpp` directory and test them in your python environment.
342412

343-
### Cleanup
344-
345-
To clear the cache.
346-
347-
```bash
348-
make clean
349-
```
350-
351413
## References
352414

353415
- [stable-diffusion.cpp](https://github.com/leejet/stable-diffusion.cpp)

assets/newton_man/newton_0.jpg

311 KB
Loading

assets/newton_man/newton_1.jpg

52.9 KB
Loading

assets/newton_man/newton_2.png

1.42 MB
Loading

assets/newton_man/newton_3.jpg

25.7 KB
Loading

pyproject.toml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,9 @@ dynamic = ["version"]
88
description = "Python bindings for the stable-diffusion.cpp library"
99
readme = "README.md"
1010
license = { text = "MIT" }
11-
authors = [
12-
{ name = "William Murray" },
13-
]
14-
maintainers = [
15-
{ name = "William Murray" },
16-
]
17-
dependencies = [
18-
"typing-extensions>=4.5.0",
19-
"pillow>=10.2.0",
20-
]
11+
authors = [{ name = "William Murray" }]
12+
maintainers = [{ name = "William Murray" }]
13+
dependencies = ["typing-extensions>=4.5.0", "pillow>=10.2.0"]
2114
keywords = [
2215
"diffusion",
2316
"stable-diffusion",
@@ -54,3 +47,9 @@ Documentation = "https://github.com/william-murray1204/stable-diffusion-cpp-pyth
5447

5548
[tool.black]
5649
line-length = 130
50+
51+
[tool.isort]
52+
profile = "black"
53+
known_local_folder = ["stable_diffusion_cpp"]
54+
remove_redundant_aliases = true
55+
length_sort = true

stable_diffusion_cpp/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
# isort: off
12
from .stable_diffusion_cpp import *
23
from .stable_diffusion import *
34

4-
__version__ = "0.2.1"
5+
# isort: on
6+
7+
__version__ = "0.2.2"

stable_diffusion_cpp/_internals.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import os
22
from contextlib import ExitStack
33

4-
from ._utils import suppress_stdout_stderr
5-
64
import stable_diffusion_cpp.stable_diffusion_cpp as sd_cpp
75

6+
from ._utils import suppress_stdout_stderr
87

98
# ============================================
109
# Stable Diffusion Model
@@ -39,6 +38,7 @@ def __init__(
3938
keep_clip_on_cpu: bool,
4039
keep_control_net_cpu: bool,
4140
keep_vae_on_cpu: bool,
41+
diffusion_flash_attn: bool,
4242
verbose: bool,
4343
):
4444
self.model_path = model_path
@@ -61,6 +61,7 @@ def __init__(
6161
self.keep_clip_on_cpu = keep_clip_on_cpu
6262
self.keep_control_net_cpu = keep_control_net_cpu
6363
self.keep_vae_on_cpu = keep_vae_on_cpu
64+
self.diffusion_flash_attn = diffusion_flash_attn
6465
self.verbose = verbose
6566

6667
self._exit_stack = ExitStack()
@@ -103,6 +104,7 @@ def __init__(
103104
self.schedule,
104105
self.keep_clip_on_cpu,
105106
self.keep_control_net_cpu,
107+
self.diffusion_flash_attn,
106108
self.keep_vae_on_cpu,
107109
)
108110

@@ -142,12 +144,10 @@ def __init__(
142144
self,
143145
upscaler_path: str,
144146
n_threads: int,
145-
wtype: int,
146147
verbose: bool,
147148
):
148149
self.upscaler_path = upscaler_path
149150
self.n_threads = n_threads
150-
self.wtype = wtype
151151
self.verbose = verbose
152152
self._exit_stack = ExitStack()
153153

@@ -163,7 +163,7 @@ def __init__(
163163
raise ValueError(f"Upscaler model path does not exist: {upscaler_path}")
164164

165165
# Load the image upscaling model ctx
166-
self.upscaler = sd_cpp.new_upscaler_ctx(upscaler_path.encode("utf-8"), self.n_threads, self.wtype)
166+
self.upscaler = sd_cpp.new_upscaler_ctx(upscaler_path.encode("utf-8"), self.n_threads)
167167

168168
# Check if the model was loaded successfully
169169
if self.upscaler is None:

0 commit comments

Comments
 (0)