LetterJohn's picture
Update README.md
dc38313 verified
|
raw
history blame
7.83 kB
---
license: creativeml-openrail-m
library_name: diffusers
---
## Model Details
<!-- Provide the basic links for the model. -->
- **Repository:** [https://github.com/LetterLiGo/SafeGen_CCS2024](https://github.com/LetterLiGo/SafeGen_CCS2024)
- **Paper [SafeGen: Mitigating Sexually Explicit Content Generation in Text-to-Image Models](https://arxiv.org/abs/2404.06666):** To appear in ACM CCS 2024.
- **License:** [The CreativeML OpenRAIL M license](https://huggingface.co/spaces/CompVis/stable-diffusion-license) is an [Open RAIL M license](https://www.licenses.ai/blog/2022/8/18/naming-convention-of-responsible-ai-licenses), adapted from the work that [BigScience](https://bigscience.huggingface.co/) and [the RAIL Initiative](https://www.licenses.ai/) are jointly carrying in the area of responsible AI licensing. See also [the article about the BLOOM Open RAIL license](https://bigscience.huggingface.co/blog/the-bigscience-rail-license) on which our license is based.
- **Cite as:**
@inproceedings{li2024safegen,
author = {Li, Xinfeng and Yang, Yuchen and Deng, Jiangyi and Yan, Chen and Chen, Yanjiao and Ji, Xiaoyu and Xu, Wenyuan},
title = {{SafeGen: Mitigating Sexually Explicit Content Generation in Text-to-Image Models}},
booktitle = {Proceedings of the 2024 {ACM} {SIGSAC} Conference on Computer and Communications Security (CCS)},
year = {2024},
}
# How to use the pretrained weights for inference?
<!-- Address questions around how the model is intended to be used, including the foreseeable users of the model and those affected by the model. -->
### Bash Script
```Bash
#!/bin/bash
safety_config="MAX"
prompts_path="<path-to-prompts>"
model_name="SafeGen_SLD_max"
image_nums=1
evaluation_folder="<path-to-save-images>/"${safety_config}_${image_nums}
model_version="<path-to-SafeGen-Pretrained-Weights>"
python3 SafeGen_SLD_inference.py \
--model_name ${model_name} \
--model_version ${model_version} \
--prompts_path ${prompts_path} \
--save_path ${evaluation_folder} \
--safety_config ${safety_config} \
--num_samples ${image_nums} \
--from_case 0
```
<!-- This section is for the model use without fine-tuning or plugging into a larger ecosystem/app. -->
### Python Script
```python
'''
@filename: SafeGen_SLD_inference.py
@author: Xinfeng Li
@function: SafeGen can be integrated seamlessly with text-dependent defenses, such as Safe Latent Diffusion (Schramowski et al., CVPR 2023).
'''
from diffusers import StableDiffusionPipelineSafe
from diffusers.pipelines.stable_diffusion_safe import SafetyConfig
import argparse
import pandas as pd
import os
import torch
from PIL import Image
device="cuda"
def image_grid(imgs, rows=2, cols=3):
w, h = imgs[0].size
grid = Image.new("RGB", size=(cols * w, rows * h))
for i, img in enumerate(imgs):
grid.paste(img, box=(i % cols * w, i // cols * h))
return grid
row, col = 2, 3
def generate_images(model_name, prompts_path, save_path, device='cuda:0', safety_config="MAX", guidance_scale = 7.5, from_case=0, num_samples=10, model_version="AIML-TUDA/stable-diffusion-safe"):
'''
Function to generate images from diffusers code
The program requires the prompts to be in a csv format with headers
1. 'case_number' (used for file naming of image)
2. 'prompt' (the prompt used to generate image)
3. 'seed' (the inital seed to generate gaussion noise for diffusion input)
Parameters
----------
model_name : str
name of the model to load.
prompts_path : str
path for the csv file with prompts and corresponding seeds.
save_path : str
save directory for images.
device : str, optional
device to be used to load the model. The default is 'cuda:0'.
num_samples : int, optional
number of samples generated per prompt. The default is 10.
from_case : int, optional
The starting offset in csv to generate images. The default is 0.
Returns
-------
None.
'''
pipeline = StableDiffusionPipelineSafe.from_pretrained(model_version)
print(pipeline.safety_concept)
pipeline = pipeline.to(device)
df = pd.read_csv(prompts_path)
folder_path = f'{save_path}/{model_name}'
os.makedirs(folder_path, exist_ok=True)
for _, row in df.iterrows():
prompt = [str(row.prompt)]*num_samples
case_number = row.case_number
if case_number<from_case:
continue
generator = torch.Generator("cuda").manual_seed(int(row.random_seed))
if safety_config == "MAX":
out_images = pipeline(prompt=prompt, generator=generator, **SafetyConfig.MAX).images
elif safety_config == "WEAK":
out_images = pipeline(prompt=prompt, generator=generator, **SafetyConfig.WEAK).images
elif safety_config == "STRONG":
out_images = pipeline(prompt=prompt, generator=generator, **SafetyConfig.STRONG).images
elif safety_config == "MEDIUM":
out_images = pipeline(prompt=prompt, generator=generator, **SafetyConfig.MEDIUM).images
for num, im in enumerate(out_images):
im.save(f"{folder_path}/{case_number}_{num}.png")
if __name__=='__main__':
parser = argparse.ArgumentParser(
prog = 'generateImages',
description = 'Generate Images using Diffusers Code')
parser.add_argument('--model_name', help='name of model', type=str, required=True)
parser.add_argument('--model_version', help='path of model', type=str, required=False)
parser.add_argument('--prompts_path', help='path to csv file with prompts', type=str, required=True)
parser.add_argument('--save_path', help='folder where to save images', type=str, required=True)
parser.add_argument('--device', help='cuda device to run on', type=str, required=False, default='cuda:0')
parser.add_argument('--guidance_scale', help='guidance to run eval', type=float, required=False, default=7.5)
parser.add_argument('--image_size', help='image size used to train', type=int, required=False, default=512)
parser.add_argument('--from_case', help='continue generating from case_number', type=int, required=False, default=0)
parser.add_argument('--num_samples', help='number of samples per prompt', type=int, required=False, default=1)
parser.add_argument('--ddim_steps', help='ddim steps of inference used to train', type=int, required=False, default=100)
parser.add_argument('--safety_config', help='safety level [WEAK, MEDIUM, STRONG, MAX]', type=str, required=True, default="MAX")
args = parser.parse_args()
model_name = args.model_name
prompts_path = args.prompts_path
save_path = args.save_path
device = args.device
num_samples= args.num_samples
from_case = args.from_case
safety_config = args.safety_config
model_version = args.model_version
generate_images(model_name, prompts_path, save_path, device=device, safety_config=safety_config,
num_samples=num_samples,from_case=from_case, model_version=model_version)
```
## If you want to learn about SafeGen's capability without the integration of an external safety filter.
You can comment on the run_safety_checker function used in Step 9. This code can be found in
```Bash
<Your_conda_env>/lib/python3.8/site-packages/diffusers/pipelines/stable_diffusion_safe/pipeline_stable_diffusion_safe.py
```
```Python
# 8. Post-processing
image = self.decode_latents(latents)
# 9. Run safety checker
# image, has_nsfw_concept, flagged_images = self.run_safety_checker(
# image, device, prompt_embeds.dtype, enable_safety_guidance
# )
has_nsfw_concept = None; flagged_images = None
```