Skip to content

Commit a198c6e

Browse files
Merge branch 'dev'
2 parents fdc1a60 + 9cdf41b commit a198c6e

26 files changed

+326
-55
lines changed

README.md

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ CMAKE_ARGS="-DSD_VULKAN=ON" pip install stable-diffusion-cpp-python
131131
<details>
132132
<summary>Using SYCL</summary>
133133

134-
Using SYCL runs the computation on an Intel GPU. Please make sure you have installed the related driver and [Intel® oneAPI Base toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html) before starting. For more details refer to [llama.cpp SYCL backend](https://github.com/ggerganov/llama.cpp/blob/master/docs/backend/SYCL.md#linux).
134+
Using SYCL runs the computation on an Intel GPU. Please make sure you have installed the related driver and [Intel® oneAPI Base toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html) before starting. For more details refer to [llama.cpp SYCL backend](https://github.com/ggml-org/llama.cpp/blob/master/docs/backend/SYCL.md#linux).
135135

136136
```bash
137137
# Export relevant ENV variables
@@ -268,11 +268,15 @@ Below is a short example demonstrating how to use the high-level API to generate
268268
### <u>Text to Image</u>
269269
270270
```python
271+
from PIL import Image
271272
from stable_diffusion_cpp import StableDiffusion
272273
273-
def callback(step: int, steps: int, time: float):
274+
def progress_callback(step: int, steps: int, time: float):
274275
print("Completed step: {} of {}".format(step, steps))
275276
277+
def preview_callback(step: int, images: list[Image.Image], is_noisy: bool):
278+
images[0].save(f"{PREVIEW_OUTPUT_DIR}/{step}.png")
279+
276280
stable_diffusion = StableDiffusion(
277281
model_path="../models/v1-5-pruned-emaonly.safetensors",
278282
# wtype="default", # Weight type (e.g. "q8_0", "f16", etc) (The "default" setting is automatically applied and determines the weight type of a model file)
@@ -281,8 +285,11 @@ output = stable_diffusion.generate_image(
281285
prompt="a lovely cat",
282286
width=512,
283287
height=512,
284-
progress_callback=callback,
288+
progress_callback=progress_callback,
285289
# seed=1337, # Uncomment to set a specific seed (use -1 for a random seed)
290+
preview_method="proj",
291+
preview_interval=2, # Call every 2 steps
292+
preview_callback=preview_callback,
286293
)
287294
output[0].save("output.png") # Output returned as list of PIL Images
288295
@@ -388,6 +395,12 @@ Download the weights from the links below:
388395
- Otherwise, download chroma's safetensors from [lodestones/Chroma1-Flash](https://huggingface.co/lodestones/Chroma1-Flash), [lodestones/Chroma1-Base](https://huggingface.co/lodestones/Chroma1-Base) or [lodestones/Chroma1-HD](https://huggingface.co/lodestones/Chroma1-HD) ([lodestones/Chroma](https://huggingface.co/lodestones/Chroma) is DEPRECATED)
389396
- The `vae` and `t5xxl` models are the same as for FLUX image generation linked above (`clip_l` not required).
390397
398+
or Chroma Radiance models from:
399+
400+
- safetensors: https://huggingface.co/lodestones/Chroma1-Radiance/tree/main
401+
- gguf: https://huggingface.co/silveroxides/Chroma1-Radiance-GGUF/tree/main
402+
- t5xxl: https://huggingface.co/comfyanonymous/flux_text_encoders/blob/main/t5xxl_fp16.safetensors
403+
391404
```python
392405
from stable_diffusion_cpp import StableDiffusion
393406
@@ -407,6 +420,12 @@ output = stable_diffusion.generate_image(
407420
408421
---
409422
423+
### <u>Some SD1.x and SDXL distilled models</u>
424+
425+
See [docs/distilled_sd.md](./docs/distilled_sd.md) for instructions on using distilled SD models.
426+
427+
---
428+
410429
### <u>SD3.5 Image Generation</u>
411430
412431
Download the weights from the links below:
@@ -712,17 +731,19 @@ stable_diffusion.convert(
712731
713732
---
714733
715-
### <u>Listing GGML model and RNG types, schedulers and sample methods</u>
734+
### <u>Listing GGML model/prediction/RNG types, sample/preview methods and schedulers</u>
716735
717-
Access the GGML model and RNG types, schedulers, and sample methods via the following maps:
736+
Access the GGML model/prediction/RNG types, sample/preview methods and schedulers via the following maps:
718737
719738
```python
720-
from stable_diffusion_cpp import GGML_TYPE_MAP, RNG_TYPE_MAP, SCHEDULER_MAP, SAMPLE_METHOD_MAP
739+
from stable_diffusion_cpp import GGML_TYPE_MAP, RNG_TYPE_MAP, SCHEDULER_MAP, SAMPLE_METHOD_MAP, PREDICTION_MAP, PREVIEW_MAP
721740
722741
print("GGML model types:", list(GGML_TYPE_MAP))
723742
print("RNG types:", list(RNG_TYPE_MAP))
724743
print("Schedulers:", list(SCHEDULER_MAP))
725744
print("Sample methods:", list(SAMPLE_METHOD_MAP))
745+
print("Prediction types:", list(PREDICTION_MAP))
746+
print("Preview methods:", list(PREVIEW_MAP))
726747
```
727748
728749
---
@@ -778,7 +799,7 @@ Now you can make changes to the code within the `stable_diffusion_cpp` directory
778799
779800
- [stable-diffusion.cpp](https://github.com/leejet/stable-diffusion.cpp)
780801
- [llama-cpp-python](https://github.com/abetlen/llama-cpp-python)
781-
- [llama.cpp](https://github.com/ggerganov/llama.cpp)
802+
- [llama.cpp](https://github.com/ggml-org/llama.cpp)
782803
- [whisper-cpp-python](https://github.com/carloscdias/whisper-cpp-python)
783804
- [Golang stable-diffusion](https://github.com/seasonjs/stable-diffusion)
784805
- [StableDiffusion.NET](https://github.com/DarthAffe/StableDiffusion.NET)

docs/distilled_sd.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Running distilled models: SSD1B and SDx.x with tiny U-Nets
2+
3+
## Preface
4+
5+
These models feature a reduced U-Net architecture. Unlike standard SDXL models, the SSD-1B U-Net contains only one middle block and fewer attention layers in its up- and down-blocks, resulting in significantly smaller file sizes. Using these models can reduce inference time by more than 33%. For more details, refer to Segmind's paper: https://arxiv.org/abs/2401.02677v1.
6+
Similarly, SD1.x- and SD2.x-style models with a tiny U-Net consist of only 6 U-Net blocks, leading to very small files and time savings of up to 50%. For more information, see the paper: https://arxiv.org/pdf/2305.15798.pdf.
7+
8+
## SSD1B
9+
10+
Note that not all of these models follow the standard parameter naming conventions. However, several useful SSD-1B models are available online, such as:
11+
12+
* https://huggingface.co/segmind/SSD-1B/resolve/main/SSD-1B-A1111.safetensors
13+
* https://huggingface.co/hassenhamdi/SSD-1B-fp8_e4m3fn/resolve/main/SSD-1B_fp8_e4m3fn.safetensors
14+
15+
Useful LoRAs are also available:
16+
17+
* https://huggingface.co/seungminh/lora-swarovski-SSD-1B/resolve/main/pytorch_lora_weights.safetensors
18+
* https://huggingface.co/kylielee505/mylcmlorassd/resolve/main/pytorch_lora_weights.safetensors
19+
20+
These files can be used out-of-the-box, unlike the models described in the next section.
21+
22+
23+
## SD1.x, SD2.x with tiny U-Nets
24+
25+
These models require conversion before use. You will need a Python script provided by the diffusers team, available on GitHub:
26+
27+
* https://raw.githubusercontent.com/huggingface/diffusers/refs/heads/main/scripts/convert_diffusers_to_original_stable_diffusion.py
28+
29+
### SD2.x
30+
31+
NotaAI provides the following model online:
32+
33+
* https://huggingface.co/nota-ai/bk-sdm-v2-tiny
34+
35+
Creating a .safetensors file involves two steps. First, run this short Python script to download the model from Hugging Face:
36+
37+
```python
38+
from diffusers import StableDiffusionPipeline
39+
pipe = StableDiffusionPipeline.from_pretrained("nota-ai/bk-sdm-v2-tiny",cache_dir="./")
40+
```
41+
42+
Second, create the .safetensors file by running:
43+
44+
```bash
45+
python convert_diffusers_to_original_stable_diffusion.py \
46+
--model_path models--nota-ai--bk-sdm-v2-tiny/snapshots/68277af553777858cd47e133f92e4db47321bc74 \
47+
--checkpoint_path bk-sdm-v2-tiny.safetensors --half --use_safetensors
48+
```
49+
50+
This will generate the **file bk-sdm-v2-tiny.safetensors**, which is now ready for use with sd.cpp.
51+
52+
### SD1.x
53+
54+
Several Tiny SD 1.x models are available online, such as:
55+
56+
* https://huggingface.co/segmind/tiny-sd
57+
* https://huggingface.co/segmind/portrait-finetuned
58+
* https://huggingface.co/nota-ai/bk-sdm-tiny
59+
60+
These models also require conversion, partly because some tensors are stored in a non-contiguous manner. To create a usable checkpoint file, follow these simple steps:
61+
Download and prepare the model using Python:
62+
63+
##### Download the model using Python on your computer, for example this way:
64+
65+
```python
66+
import torch
67+
from diffusers import StableDiffusionPipeline
68+
pipe = StableDiffusionPipeline.from_pretrained("segmind/tiny-sd")
69+
unet=pipe.unet
70+
for param in unet.parameters():
71+
param.data = param.data.contiguous() # <- important here
72+
pipe.save_pretrained("segmindtiny-sd", safe_serialization=True)
73+
```
74+
75+
##### Run the conversion script:
76+
77+
```bash
78+
python convert_diffusers_to_original_stable_diffusion.py \
79+
--model_path ./segmindtiny-sd \
80+
--checkpoint_path ./segmind_tiny-sd.ckpt --half
81+
```
82+
83+
The file segmind_tiny-sd.ckpt will be generated and is now ready for use with sd.cpp. You can follow a similar process for the other models mentioned above.
84+
85+
86+
### Another available .ckpt file:
87+
88+
* https://huggingface.co/ClashSAN/small-sd/resolve/main/tinySDdistilled.ckpt
89+
90+
To use this file, you must first adjust its non-contiguous tensors:
91+
92+
```python
93+
import torch
94+
ckpt = torch.load("tinySDdistilled.ckpt", map_location=torch.device('cpu'))
95+
for key, value in ckpt['state_dict'].items():
96+
if isinstance(value, torch.Tensor):
97+
ckpt['state_dict'][key] = value.contiguous()
98+
torch.save(ckpt, "tinySDdistilled_fixed.ckpt")
99+
```

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ line-length = 130
5959

6060
[tool.isort]
6161
profile = "black"
62-
known_local_folder = ["stable_diffusion_cpp"]
62+
known_local_folder = ["stable_diffusion_cpp", "tests"]
6363
remove_redundant_aliases = true
6464
length_sort = true
6565

stable_diffusion_cpp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# isort: on
66

7-
__version__ = "0.3.6"
7+
__version__ = "0.3.7"

stable_diffusion_cpp/_internals.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def __init__(
4343
keep_control_net_on_cpu: bool,
4444
keep_vae_on_cpu: bool,
4545
diffusion_flash_attn: bool,
46+
tae_preview_only: bool,
4647
diffusion_conv_direct: bool,
4748
vae_conv_direct: bool,
4849
force_sdxl_vae_conv_scale: bool,
@@ -81,6 +82,7 @@ def __init__(
8182
keep_control_net_on_cpu=keep_control_net_on_cpu,
8283
keep_vae_on_cpu=keep_vae_on_cpu,
8384
diffusion_flash_attn=diffusion_flash_attn,
85+
tae_preview_only=tae_preview_only,
8486
diffusion_conv_direct=diffusion_conv_direct,
8587
vae_conv_direct=vae_conv_direct,
8688
force_sdxl_vae_conv_scale=force_sdxl_vae_conv_scale,

0 commit comments

Comments
 (0)