hysts HF staff commited on
Commit
448d919
1 Parent(s): 4149107
Files changed (6) hide show
  1. .pre-commit-config.yaml +50 -0
  2. .vscode/settings.json +21 -0
  3. LICENSE +21 -0
  4. app.py +149 -0
  5. requirements.txt +5 -0
  6. style.css +10 -0
.pre-commit-config.yaml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.4.0
4
+ hooks:
5
+ - id: check-executables-have-shebangs
6
+ - id: check-json
7
+ - id: check-merge-conflict
8
+ - id: check-shebang-scripts-are-executable
9
+ - id: check-toml
10
+ - id: check-yaml
11
+ - id: end-of-file-fixer
12
+ - id: mixed-line-ending
13
+ args: ["--fix=lf"]
14
+ - id: requirements-txt-fixer
15
+ - id: trailing-whitespace
16
+ - repo: https://github.com/myint/docformatter
17
+ rev: v1.7.5
18
+ hooks:
19
+ - id: docformatter
20
+ args: ["--in-place"]
21
+ - repo: https://github.com/pycqa/isort
22
+ rev: 5.12.0
23
+ hooks:
24
+ - id: isort
25
+ args: ["--profile", "black"]
26
+ - repo: https://github.com/pre-commit/mirrors-mypy
27
+ rev: v1.5.1
28
+ hooks:
29
+ - id: mypy
30
+ args: ["--ignore-missing-imports"]
31
+ additional_dependencies: ["types-python-slugify", "types-requests", "types-PyYAML"]
32
+ - repo: https://github.com/psf/black
33
+ rev: 23.7.0
34
+ hooks:
35
+ - id: black
36
+ language_version: python3.10
37
+ args: ["--line-length", "119"]
38
+ - repo: https://github.com/kynan/nbstripout
39
+ rev: 0.6.1
40
+ hooks:
41
+ - id: nbstripout
42
+ args: ["--extra-keys", "metadata.interpreter metadata.kernelspec cell.metadata.pycharm"]
43
+ - repo: https://github.com/nbQA-dev/nbQA
44
+ rev: 1.7.0
45
+ hooks:
46
+ - id: nbqa-black
47
+ - id: nbqa-pyupgrade
48
+ args: ["--py37-plus"]
49
+ - id: nbqa-isort
50
+ args: ["--float-to-top"]
.vscode/settings.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "[python]": {
3
+ "editor.defaultFormatter": "ms-python.black-formatter",
4
+ "editor.formatOnType": true,
5
+ "editor.codeActionsOnSave": {
6
+ "source.organizeImports": true
7
+ }
8
+ },
9
+ "black-formatter.args": [
10
+ "--line-length=119"
11
+ ],
12
+ "isort.args": ["--profile", "black"],
13
+ "flake8.args": [
14
+ "--max-line-length=119"
15
+ ],
16
+ "ruff.args": [
17
+ "--line-length=119"
18
+ ],
19
+ "editor.formatOnSave": true,
20
+ "files.insertFinalNewline": true
21
+ }
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2023 hysts
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+
3
+ import random
4
+
5
+ import gradio as gr
6
+ import numpy as np
7
+ import PIL.Image
8
+ import torch
9
+ from diffusers import DDPMScheduler, StableDiffusionXLAdapterPipeline, T2IAdapter
10
+
11
+ DESCRIPTION = "# T2I-Adapter-SDXL Sketch"
12
+
13
+ if not torch.cuda.is_available():
14
+ DESCRIPTION += "\n<p>Running on CPU 🥶 This demo does not work on CPU.</p>"
15
+
16
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
17
+ if torch.cuda.is_available():
18
+ model_id = "stabilityai/stable-diffusion-xl-base-1.0"
19
+ adapter = T2IAdapter.from_pretrained(
20
+ "Adapter/t2iadapter",
21
+ subfolder="sketch_sdxl_1.0",
22
+ torch_dtype=torch.float16,
23
+ adapter_type="full_adapter_xl",
24
+ )
25
+ scheduler = DDPMScheduler.from_pretrained(model_id, subfolder="scheduler")
26
+ pipe = StableDiffusionXLAdapterPipeline.from_pretrained(
27
+ model_id,
28
+ adapter=adapter,
29
+ safety_checker=None,
30
+ torch_dtype=torch.float16,
31
+ variant="fp16",
32
+ scheduler=scheduler,
33
+ )
34
+ pipe.to(device)
35
+ else:
36
+ pipe = None
37
+
38
+ MAX_SEED = np.iinfo(np.int32).max
39
+
40
+
41
+ def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
42
+ if randomize_seed:
43
+ seed = random.randint(0, MAX_SEED)
44
+ return seed
45
+
46
+
47
+ def run(
48
+ image: PIL.Image.Image,
49
+ prompt: str,
50
+ negative_prompt: str,
51
+ num_steps=50,
52
+ guidance_scale=7.5,
53
+ seed=0,
54
+ ) -> PIL.Image.Image:
55
+ # Convert the input image, which is a boolean image, to a grayscale image whose value is 0 or 255.
56
+ image = image.convert("L")
57
+
58
+ generator = torch.Generator(device=device).manual_seed(seed)
59
+ out = pipe(
60
+ prompt=prompt,
61
+ negative_prompt=negative_prompt,
62
+ image=image,
63
+ num_inference_steps=num_steps,
64
+ generator=generator,
65
+ guidance_scale=guidance_scale,
66
+ ).images[0]
67
+ return out
68
+
69
+
70
+ with gr.Blocks() as demo:
71
+ gr.Markdown(DESCRIPTION)
72
+ with gr.Row():
73
+ with gr.Column():
74
+ image = gr.Image(
75
+ source="canvas",
76
+ tool="sketch",
77
+ type="pil",
78
+ image_mode="1",
79
+ invert_colors=True,
80
+ shape=(1024, 1024),
81
+ brush_radius=20,
82
+ height=600,
83
+ )
84
+ prompt = gr.Textbox(label="Prompt")
85
+ run_button = gr.Button("Run")
86
+ with gr.Accordion("Advanced options", open=False):
87
+ negative_prompt = gr.Textbox(
88
+ label="Negative prompt", value="extra digit, fewer digits, cropped, worst quality, low quality"
89
+ )
90
+ num_steps = gr.Slider(
91
+ label="Number of steps",
92
+ minimum=1,
93
+ maximum=100,
94
+ step=1,
95
+ value=50,
96
+ )
97
+ guidance_scale = gr.Slider(
98
+ label="Guidance scale",
99
+ minimum=0.1,
100
+ maximum=30.0,
101
+ step=0.1,
102
+ value=7.5,
103
+ )
104
+ seed = gr.Slider(
105
+ label="Seed",
106
+ minimum=0,
107
+ maximum=MAX_SEED,
108
+ step=1,
109
+ value=0,
110
+ )
111
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
112
+ with gr.Column():
113
+ result = gr.Image(label="Result", height=600)
114
+
115
+ inputs = [
116
+ image,
117
+ prompt,
118
+ negative_prompt,
119
+ num_steps,
120
+ guidance_scale,
121
+ seed,
122
+ ]
123
+ prompt.submit(
124
+ fn=randomize_seed_fn,
125
+ inputs=[seed, randomize_seed],
126
+ outputs=seed,
127
+ queue=False,
128
+ api_name=False,
129
+ ).then(
130
+ fn=run,
131
+ inputs=inputs,
132
+ outputs=result,
133
+ api_name=False,
134
+ )
135
+ run_button.click(
136
+ fn=randomize_seed_fn,
137
+ inputs=[seed, randomize_seed],
138
+ outputs=seed,
139
+ queue=False,
140
+ api_name=False,
141
+ ).then(
142
+ fn=run,
143
+ inputs=inputs,
144
+ outputs=result,
145
+ api_name="run",
146
+ )
147
+
148
+ if __name__ == "__main__":
149
+ demo.queue(max_size=20).launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ git+https://github.com/huggingface/diffusers
2
+ gradio==3.42.0
3
+ Pillow==10.0.0
4
+ torch==2.0.1
5
+ transformers==4.33.0
style.css ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ h1 {
2
+ text-align: center;
3
+ }
4
+
5
+ #duplicate-button {
6
+ margin: auto;
7
+ color: #fff;
8
+ background: #1565c0;
9
+ border-radius: 100vh;
10
+ }