File size: 5,660 Bytes
b00eff9 57f7c80 c817021 57f7c80 c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 6334eed c817021 1669423 c817021 6334eed c817021 6334eed |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
---
license: openrail++
---
# Contents
This repository contains:
1. Half-Precision LoRA versions of https://huggingface.co/mhdang/dpo-sdxl-text2image-v1 and https://huggingface.co/mhdang/dpo-sd1.5-text2image-v1.
2. Full-Precision offset versions of https://huggingface.co/mhdang/dpo-sdxl-text2image-v1 and https://huggingface.co/mhdang/dpo-sd1.5-text2image-v1.
# Creation
## LoRA
The LoRA were created using Kohya SS.
1.5: https://civitai.com/models/240850/sd15-direct-preference-optimization-dpo extracted from https://huggingface.co/fp16-guy/Stable-Diffusion-v1-5_fp16_cleaned/blob/main/sd_1.5.safetensors.
XL: https://civitai.com/models/238319/sd-xl-dpo-finetune-direct-preference-optimization extracted from https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0_0.9vae.safetensors
## Offsets
The offsets were calculated in Pytorch using the following formula:
1.5: https://huggingface.co/mhdang/dpo-sd1.5-text2image-v1/blob/main/unet/diffusion_pytorch_model.safetensors - https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/unet/diffusion_pytorch_model.bin
XL: https://huggingface.co/mhdang/dpo-sdxl-text2image-v1/blob/main/unet/diffusion_pytorch_model.safetensors - https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/unet/diffusion_pytorch_model.safetensors
These can be added directly to any initialized UNet to inject DPO training into it. See the code below for usage (diffusers only.)
# License
These models are derivces from all OpenRail++ models, and are licensed under OpenRail++ themselves.
# Usage
## Offsets
```py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from diffusers.models import UNet2DConditionModel
def inject_dpo(unet: UNet2DConditionModel, dpo_offset_path: str, device: str, strict: bool = False) -> None:
"""
Injects DPO weights directly into your UNet.
Args:
unet (`UNet2DConditionModel`)
The initialized UNet from your pipeline.
dpo_offset_path (`str`)
The path to the `.safetensors` file downloaded from https://huggingface.co/benjamin-paine/sd-dpo-offsets/.
Make sure you're using the right file for the right base model.
strict (`bool`, *optional*)
Whether or not to raise errors when a weight cannot be applied. Defaults to false.
"""
from safetensors import safe_open
with safe_open(dpo_offset_path, framework="pt", device=device) as f:
for key in f.keys():
key_parts = key.split(".")
current_layer = unet
for key_part in key_parts[:-1]:
current_layer = getattr(current_layer, key_part, None)
if current_layer is None:
break
if current_layer is None:
if strict:
raise IOError(f"Couldn't find a layer to inject key {key} in.")
continue
layer_param = getattr(current_layer, key_parts[-1], None)
if layer_param is None:
if strict:
raise IOError(f"Couldn't get weight parameter for key {key}")
continue
layer_param.data += f.get_tensor(key)
```
Now you can use this function like so:
```py
from diffusers import StableDiffusionPipeline
import huggingface_hub
import torch
# load sdv15 pipeline
device = "cuda"
model_id = "Lykon/dreamshaper-8"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe.to(device)
# make image
prompt = "Two cats playing chess on a tree branch"
generator = torch.Generator(device=device)
generator.manual_seed(123456789)
image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]
image.save("cats_playing_chess.png")
# download DPO offsets
dpo_offset_path = huggingface_hub.hf_hub_download("benjamin-paine/sd-dpo-offsets", "sd_v15_unet_dpo_offset.safetensors")
# inject
inject_dpo(pipe.unet, dpo_offset_path, device)
# make image again
generator.manual_seed(123456789)
image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]
image.save("cats_playing_chess_dpo.png")
```
`cats_playing_chess.png`
![image/png](https://cdn-uploads.huggingface.co/production/uploads/64429aaf7feb866811b12f73/KqAohfKMXKVGTDpuBhhx6.png)
`cats_playing_chess_dpo.png`
![image/png](https://cdn-uploads.huggingface.co/production/uploads/64429aaf7feb866811b12f73/fY9j1q8ZazyNP4JbD0TTU.png)
Or for XL:
```py
from diffusers import StableDiffusionXLPipeline
import huggingface_hub
import torch
# load sdv15 pipeline
device = "cuda"
model_id = "Lykon/dreamshaper-xl-1-0"
pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
pipe.to(device)
# make image
prompt = "Two cats playing chess on a tree branch"
generator = torch.Generator(device=device)
generator.manual_seed(123456789)
image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]
image.save("cats_playing_chess_xl.png")
# download DPO offsets
dpo_offset_path = huggingface_hub.hf_hub_download("benjamin-paine/sd-dpo-offsets", "sd_xl_unet_dpo_offset.safetensors")
# inject
inject_dpo(pipe.unet, dpo_offset_path, device)
# make image again
generator.manual_seed(123456789)
image = pipe(prompt, guidance_scale=7.5, generator=generator).images[0]
image.save("cats_playing_chess_xl_dpo.png")
```
`cats_playing_chess_xl.png`
![image/png](https://cdn-uploads.huggingface.co/production/uploads/64429aaf7feb866811b12f73/BufmVzFBsoYX_jipzErIo.png)
`cats_playing_chess_xl_dpo.png`
![image/png](https://cdn-uploads.huggingface.co/production/uploads/64429aaf7feb866811b12f73/Rj9FXI-vmrMwvepMSLMe7.png) |