File size: 6,798 Bytes
1cd4045
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import random

import spaces
import torch
import gradio as gr
from diffusers import DiffusionPipeline

BASE_MODEL = "krea/Krea-2-Turbo"
CUSTOM_PIPELINE = "ostris/Krea2OstrisEdit"
LORA_REPO = "ostris/krea2_turbo_style_reference"
LORA_WEIGHT = "krea2_style_reference.safetensors"

DTYPE = torch.bfloat16
MAX_SEED = 2**31 - 1


pipe = DiffusionPipeline.from_pretrained(
    BASE_MODEL,
    custom_pipeline=CUSTOM_PIPELINE,
    torch_dtype=DTYPE,
    trust_remote_code=True,
)
pipe.to("cuda")
pipe.load_lora_weights(LORA_REPO, weight_name=LORA_WEIGHT)


@spaces.GPU(duration=90, size="large")
def generate(
    prompt,
    reference_image,
    use_reference,
    lora_scale=1.0,
    steps=8,
    guidance=0.0,
    width=1024,
    height=1024,
    seed=0,
    randomize_seed=True,
    progress=gr.Progress(track_tqdm=True),
):
    if not prompt or not prompt.strip():
        raise gr.Error("Please enter a prompt.")
    if use_reference and reference_image is None:
        raise gr.Error("Please upload a reference image or disable the reference option.")

    if randomize_seed or seed is None:
        seed = random.randint(0, MAX_SEED)
    seed = int(seed)

    if lora_scale is None:
        lora_scale = 1.0
    if steps is None:
        steps = 8
    if guidance is None:
        guidance = 0.0
    if width is None:
        width = 1024
    if height is None:
        height = 1024

    # Snap dimensions to multiples of 16 (vae_scale_factor * patch_size = 16)
    multiple = 16
    width = ((int(width) + multiple - 1) // multiple) * multiple
    height = ((int(height) + multiple - 1) // multiple) * multiple

    generator = torch.Generator("cuda").manual_seed(seed)

    pipe_kwargs = dict(
        prompt=prompt,
        num_inference_steps=int(steps),
        guidance_scale=float(guidance),
        width=width,
        height=height,
        generator=generator,
        attention_kwargs={"scale": float(lora_scale)},
    )
    if use_reference and reference_image is not None:
        pipe_kwargs["image"] = reference_image

    image = pipe(**pipe_kwargs).images[0]
    return image, seed


CSS = """
#page { max-width: 1100px; margin: 0 auto; padding: 4px 8px 32px; }
#header { padding: 24px 4px 18px; border-bottom: 1px solid #e5e5e5; margin-bottom: 20px; }
#header h1 { font-size: 32px; font-weight: 700; margin: 0 0 6px; letter-spacing: -0.02em; }
#header .subtitle { font-size: 15px; color: #666; margin: 0; max-width: 70ch; line-height: 1.5; }
#header .links { margin-top: 12px; display: flex; gap: 16px; }
#header .links a {
    font-size: 13px; color: #888; text-decoration: none;
    border: 1px solid #ddd; border-radius: 6px; padding: 4px 10px;
}
#header .links a:hover { color: #333; border-color: #aaa; }
footer { display: none !important; }
"""

HEADER = """
<div id="header">
  <h1>Krea 2 Ostris Edit</h1>
  <p class="subtitle">
    Reference-image conditioned image generation with
    <a href="https://huggingface.co/krea/Krea-2-Turbo" target="_blank">Krea 2 Turbo</a>
    via the
    <a href="https://huggingface.co/ostris/Krea2OstrisEdit" target="_blank">Krea2OstrisEdit</a>
    community pipeline. Upload a reference image and describe what you want — the model
    uses the reference for style, subject, or edit context. Powered by the
    <a href="https://huggingface.co/ostris/krea2_turbo_style_reference" target="_blank">Style Reference LoRA</a>.
  </p>
  <div class="links">
    <a href="https://huggingface.co/ostris/Krea2OstrisEdit" target="_blank">Pipeline ↗</a>
    <a href="https://huggingface.co/krea/Krea-2-Turbo" target="_blank">Base model ↗</a>
    <a href="https://huggingface.co/ostris/krea2_turbo_style_reference" target="_blank">LoRA ↗</a>
  </div>
</div>
"""

with gr.Blocks(title="Krea 2 Ostris Edit") as demo:
    with gr.Column(elem_id="page"):
        gr.HTML(HEADER)
        with gr.Row(equal_height=False):
            with gr.Column(scale=1):
                prompt = gr.Textbox(
                    label="Prompt",
                    lines=3,
                    placeholder="Describe what you want to generate, e.g. 'a white yeti with horns reading a book'",
                )
                use_reference = gr.Checkbox(
                    value=True,
                    label="Use reference image",
                    info="Toggle to switch between reference-conditioned and plain text-to-image mode",
                )
                reference_image = gr.Image(
                    label="Reference Image",
                    type="pil",
                    height=300,
                )
                generate_btn = gr.Button("Generate", variant="primary", size="lg")
                with gr.Accordion("Advanced", open=False):
                    lora_scale = gr.Slider(
                        0.0, 2.0, value=1.0, step=0.01,
                        label="LoRA scale",
                        info="Strength of the reference image influence",
                    )
                    steps = gr.Slider(1, 30, value=8, step=1, label="Steps")
                    guidance = gr.Slider(
                        0.0, 10.0, value=0.0, step=0.1,
                        label="Guidance scale",
                        info="Krea 2 Turbo uses 0.0 (guidance disabled)",
                    )
                    with gr.Row():
                        width = gr.Slider(512, 1536, value=1024, step=16, label="Width")
                        height = gr.Slider(512, 1536, value=1024, step=16, label="Height")
                    with gr.Row():
                        seed = gr.Slider(0, MAX_SEED, value=0, step=1, label="Seed")
                        randomize_seed = gr.Checkbox(value=True, label="Randomize seed")
            with gr.Column(scale=1):
                result = gr.Image(label="Result", format="png", height=420)
                used_seed = gr.Number(label="Seed used", visible=True, interactive=False)

        inputs = [
            prompt, reference_image, use_reference,
            lora_scale, steps, guidance,
            width, height, seed, randomize_seed,
        ]
        outputs = [result, used_seed]

        gr.Examples(
            examples=[
                ["a white yeti with horns reading a book", "examples/style_ref_clean.png", True],
                ["a futuristic city skyline at sunset, cyberpunk aesthetic", "examples/style_ref_clean.png", True],
                ["a white yeti with horns reading a book", None, False],
            ],
            inputs=[prompt, reference_image, use_reference],
            outputs=outputs,
            fn=generate,
            cache_examples=True,
            cache_mode="lazy",
        )

        gr.on([generate_btn.click, prompt.submit], generate, inputs, outputs)

if __name__ == "__main__":
    demo.launch(theme=gr.themes.Citrus(), css=CSS)