Nymbo commited on
Commit
2af0f78
·
verified ·
1 Parent(s): a50030d

Update Modules/Generate_Image.py

Browse files
Files changed (1) hide show
  1. Modules/Generate_Image.py +133 -129
Modules/Generate_Image.py CHANGED
@@ -1,129 +1,133 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import random
5
- from typing import Annotated
6
-
7
- import gradio as gr
8
- from PIL import Image
9
- from huggingface_hub import InferenceClient
10
-
11
- from app import _log_call_end, _log_call_start, _truncate_for_log
12
-
13
- HF_API_TOKEN = os.getenv("HF_READ_TOKEN")
14
-
15
-
16
- def Generate_Image(
17
- prompt: Annotated[str, "Text description of the image to generate."],
18
- model_id: Annotated[str, "Hugging Face model id in the form 'creator/model-name' (e.g., black-forest-labs/FLUX.1-Krea-dev)."] = "black-forest-labs/FLUX.1-Krea-dev",
19
- negative_prompt: Annotated[str, "What should NOT appear in the image."] = (
20
- "(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, "
21
- "missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, "
22
- "mutated, ugly, disgusting, blurry, amputation, misspellings, typos"
23
- ),
24
- steps: Annotated[int, "Number of denoising steps (1–100). Higher = slower, potentially higher quality."] = 35,
25
- cfg_scale: Annotated[float, "Classifier-free guidance scale (1–20). Higher = follow the prompt more closely."] = 7.0,
26
- sampler: Annotated[str, "Sampling method label (UI only). Common options: 'DPM++ 2M Karras', 'DPM++ SDE Karras', 'Euler', 'Euler a', 'Heun', 'DDIM'."] = "DPM++ 2M Karras",
27
- seed: Annotated[int, "Random seed for reproducibility. Use -1 for a random seed per call."] = -1,
28
- width: Annotated[int, "Output width in pixels (64–1216, multiple of 32 recommended)."] = 1024,
29
- height: Annotated[int, "Output height in pixels (64–1216, multiple of 32 recommended)."] = 1024,
30
- ) -> Image.Image:
31
- _log_call_start(
32
- "Generate_Image",
33
- prompt=_truncate_for_log(prompt, 200),
34
- model_id=model_id,
35
- steps=steps,
36
- cfg_scale=cfg_scale,
37
- seed=seed,
38
- size=f"{width}x{height}",
39
- )
40
- if not prompt or not prompt.strip():
41
- _log_call_end("Generate_Image", "error=empty prompt")
42
- raise gr.Error("Please provide a non-empty prompt.")
43
- enhanced_prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
44
- providers = ["auto", "replicate", "fal-ai"]
45
- last_error: Exception | None = None
46
- for provider in providers:
47
- try:
48
- client = InferenceClient(api_key=HF_API_TOKEN, provider=provider)
49
- image = client.text_to_image(
50
- prompt=enhanced_prompt,
51
- negative_prompt=negative_prompt,
52
- model=model_id,
53
- width=width,
54
- height=height,
55
- num_inference_steps=steps,
56
- guidance_scale=cfg_scale,
57
- seed=seed if seed != -1 else random.randint(1, 1_000_000_000),
58
- )
59
- _log_call_end("Generate_Image", f"provider={provider} size={image.size}")
60
- return image
61
- except Exception as exc: # pylint: disable=broad-except
62
- last_error = exc
63
- continue
64
- msg = str(last_error) if last_error else "Unknown error"
65
- lowered = msg.lower()
66
- if "404" in msg:
67
- raise gr.Error(f"Model not found or unavailable: {model_id}. Check the id and your HF token access.")
68
- if "503" in msg:
69
- raise gr.Error("The model is warming up. Please try again shortly.")
70
- if "401" in msg or "403" in msg:
71
- raise gr.Error("Please duplicate the space and provide a `HF_READ_TOKEN` to enable Image and Video Generation.")
72
- if ("api_key" in lowered) or ("hf auth login" in lowered) or ("unauthorized" in lowered) or ("forbidden" in lowered):
73
- raise gr.Error("Please duplicate the space and provide a `HF_READ_TOKEN` to enable Image and Video Generation.")
74
- _log_call_end("Generate_Image", f"error={_truncate_for_log(msg, 200)}")
75
- raise gr.Error(f"Image generation failed: {msg}")
76
-
77
-
78
- def build_interface() -> gr.Interface:
79
- return gr.Interface(
80
- fn=Generate_Image,
81
- inputs=[
82
- gr.Textbox(label="Prompt", placeholder="Enter a prompt", lines=2),
83
- gr.Textbox(
84
- label="Model",
85
- value="black-forest-labs/FLUX.1-Krea-dev",
86
- placeholder="creator/model-name",
87
- max_lines=1,
88
- info="<a href=\"https://huggingface.co/models?pipeline_tag=text-to-image&inference_provider=nebius,cerebras,novita,fireworks-ai,together,fal-ai,groq,featherless-ai,nscale,hyperbolic,sambanova,cohere,replicate,scaleway,publicai,hf-inference&sort=trending\" target=\"_blank\" rel=\"noopener noreferrer\">Browse models</a>",
89
- ),
90
- gr.Textbox(
91
- label="Negative Prompt",
92
- value=(
93
- "(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, "
94
- "missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, "
95
- "mutated, ugly, disgusting, blurry, amputation, misspellings, typos"
96
- ),
97
- lines=2,
98
- ),
99
- gr.Slider(minimum=1, maximum=100, value=35, step=1, label="Steps"),
100
- gr.Slider(minimum=1.0, maximum=20.0, value=7.0, step=0.1, label="CFG Scale"),
101
- gr.Radio(
102
- label="Sampler",
103
- value="DPM++ 2M Karras",
104
- choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"],
105
- ),
106
- gr.Slider(minimum=-1, maximum=1_000_000_000, value=-1, step=1, label="Seed (-1 = random)"),
107
- gr.Slider(minimum=64, maximum=1216, value=1024, step=32, label="Width"),
108
- gr.Slider(minimum=64, maximum=1216, value=1024, step=32, label="Height"),
109
- ],
110
- outputs=gr.Image(label="Generated Image"),
111
- title="Generate Image",
112
- description=(
113
- "<div style=\"text-align:center\">Generate images via Hugging Face serverless inference. "
114
- "Default model is FLUX.1-Krea-dev.</div>"
115
- ),
116
- api_description=(
117
- "Generate a single image from a text prompt using a Hugging Face model via serverless inference. "
118
- "Supports creative prompts like 'a serene mountain landscape at sunset', 'portrait of a wise owl', "
119
- "'futuristic city with flying cars'. Default model: FLUX.1-Krea-dev. "
120
- "Parameters: prompt (str), model_id (str, creator/model-name), negative_prompt (str), steps (int, 1–100), "
121
- "cfg_scale (float, 1–20), sampler (str), seed (int, -1=random), width/height (int, 64–1216). "
122
- "Returns a PIL.Image. Return the generated media to the user in this format `![Alt text](URL)`"
123
- ),
124
- flagging_mode="never",
125
- show_api=bool(os.getenv("HF_READ_TOKEN")),
126
- )
127
-
128
-
129
- __all__ = ["Generate_Image", "build_interface"]
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import random
5
+ from typing import Annotated
6
+
7
+ import gradio as gr
8
+ from PIL import Image
9
+ from huggingface_hub import InferenceClient
10
+
11
+ from app import _log_call_end, _log_call_start, _truncate_for_log
12
+ from ._docstrings import autodoc
13
+
14
+ HF_API_TOKEN = os.getenv("HF_READ_TOKEN")
15
+
16
+ # Single source of truth for the LLM-facing tool description
17
+ TOOL_SUMMARY = (
18
+ "Generate an image from a text prompt via Hugging Face serverless inference; "
19
+ "tunable model/steps/guidance/size, supports negative prompt and seed; returns a PIL.Image. "
20
+ "Return the generated media to the user in this format `![Alt text](URL)`"
21
+ )
22
+
23
+
24
+ @autodoc(
25
+ summary=TOOL_SUMMARY,
26
+ )
27
+ def Generate_Image(
28
+ prompt: Annotated[str, "Text description of the image to generate."],
29
+ model_id: Annotated[str, "Hugging Face model id in the form 'creator/model-name' (e.g., black-forest-labs/FLUX.1-Krea-dev)."] = "black-forest-labs/FLUX.1-Krea-dev",
30
+ negative_prompt: Annotated[str, "What should NOT appear in the image."] = (
31
+ "(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, "
32
+ "missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, "
33
+ "mutated, ugly, disgusting, blurry, amputation, misspellings, typos"
34
+ ),
35
+ steps: Annotated[int, "Number of denoising steps (1–100). Higher = slower, potentially higher quality."] = 35,
36
+ cfg_scale: Annotated[float, "Classifier-free guidance scale (1–20). Higher = follow the prompt more closely."] = 7.0,
37
+ sampler: Annotated[str, "Sampling method label (UI only). Common options: 'DPM++ 2M Karras', 'DPM++ SDE Karras', 'Euler', 'Euler a', 'Heun', 'DDIM'."] = "DPM++ 2M Karras",
38
+ seed: Annotated[int, "Random seed for reproducibility. Use -1 for a random seed per call."] = -1,
39
+ width: Annotated[int, "Output width in pixels (64–1216, multiple of 32 recommended)."] = 1024,
40
+ height: Annotated[int, "Output height in pixels (64–1216, multiple of 32 recommended)."] = 1024,
41
+ ) -> Image.Image:
42
+ _log_call_start(
43
+ "Generate_Image",
44
+ prompt=_truncate_for_log(prompt, 200),
45
+ model_id=model_id,
46
+ steps=steps,
47
+ cfg_scale=cfg_scale,
48
+ seed=seed,
49
+ size=f"{width}x{height}",
50
+ )
51
+ if not prompt or not prompt.strip():
52
+ _log_call_end("Generate_Image", "error=empty prompt")
53
+ raise gr.Error("Please provide a non-empty prompt.")
54
+ enhanced_prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
55
+ providers = ["auto", "replicate", "fal-ai"]
56
+ last_error: Exception | None = None
57
+ for provider in providers:
58
+ try:
59
+ client = InferenceClient(api_key=HF_API_TOKEN, provider=provider)
60
+ image = client.text_to_image(
61
+ prompt=enhanced_prompt,
62
+ negative_prompt=negative_prompt,
63
+ model=model_id,
64
+ width=width,
65
+ height=height,
66
+ num_inference_steps=steps,
67
+ guidance_scale=cfg_scale,
68
+ seed=seed if seed != -1 else random.randint(1, 1_000_000_000),
69
+ )
70
+ _log_call_end("Generate_Image", f"provider={provider} size={image.size}")
71
+ return image
72
+ except Exception as exc: # pylint: disable=broad-except
73
+ last_error = exc
74
+ continue
75
+ msg = str(last_error) if last_error else "Unknown error"
76
+ lowered = msg.lower()
77
+ if "404" in msg:
78
+ raise gr.Error(f"Model not found or unavailable: {model_id}. Check the id and your HF token access.")
79
+ if "503" in msg:
80
+ raise gr.Error("The model is warming up. Please try again shortly.")
81
+ if "401" in msg or "403" in msg:
82
+ raise gr.Error("Please duplicate the space and provide a `HF_READ_TOKEN` to enable Image and Video Generation.")
83
+ if ("api_key" in lowered) or ("hf auth login" in lowered) or ("unauthorized" in lowered) or ("forbidden" in lowered):
84
+ raise gr.Error("Please duplicate the space and provide a `HF_READ_TOKEN` to enable Image and Video Generation.")
85
+ _log_call_end("Generate_Image", f"error={_truncate_for_log(msg, 200)}")
86
+ raise gr.Error(f"Image generation failed: {msg}")
87
+
88
+
89
+ def build_interface() -> gr.Interface:
90
+ return gr.Interface(
91
+ fn=Generate_Image,
92
+ inputs=[
93
+ gr.Textbox(label="Prompt", placeholder="Enter a prompt", lines=2),
94
+ gr.Textbox(
95
+ label="Model",
96
+ value="black-forest-labs/FLUX.1-Krea-dev",
97
+ placeholder="creator/model-name",
98
+ max_lines=1,
99
+ info="<a href=\"https://huggingface.co/models?pipeline_tag=text-to-image&inference_provider=nebius,cerebras,novita,fireworks-ai,together,fal-ai,groq,featherless-ai,nscale,hyperbolic,sambanova,cohere,replicate,scaleway,publicai,hf-inference&sort=trending\" target=\"_blank\" rel=\"noopener noreferrer\">Browse models</a>",
100
+ ),
101
+ gr.Textbox(
102
+ label="Negative Prompt",
103
+ value=(
104
+ "(deformed, distorted, disfigured), poorly drawn, bad anatomy, wrong anatomy, extra limb, "
105
+ "missing limb, floating limbs, (mutated hands and fingers), disconnected limbs, mutation, "
106
+ "mutated, ugly, disgusting, blurry, amputation, misspellings, typos"
107
+ ),
108
+ lines=2,
109
+ ),
110
+ gr.Slider(minimum=1, maximum=100, value=35, step=1, label="Steps"),
111
+ gr.Slider(minimum=1.0, maximum=20.0, value=7.0, step=0.1, label="CFG Scale"),
112
+ gr.Radio(
113
+ label="Sampler",
114
+ value="DPM++ 2M Karras",
115
+ choices=["DPM++ 2M Karras", "DPM++ SDE Karras", "Euler", "Euler a", "Heun", "DDIM"],
116
+ ),
117
+ gr.Slider(minimum=-1, maximum=1_000_000_000, value=-1, step=1, label="Seed (-1 = random)"),
118
+ gr.Slider(minimum=64, maximum=1216, value=1024, step=32, label="Width"),
119
+ gr.Slider(minimum=64, maximum=1216, value=1024, step=32, label="Height"),
120
+ ],
121
+ outputs=gr.Image(label="Generated Image"),
122
+ title="Generate Image",
123
+ description=(
124
+ "<div style=\"text-align:center\">Generate images via Hugging Face serverless inference. "
125
+ "Default model is FLUX.1-Krea-dev.</div>"
126
+ ),
127
+ api_description=TOOL_SUMMARY,
128
+ flagging_mode="never",
129
+ show_api=bool(os.getenv("HF_READ_TOKEN")),
130
+ )
131
+
132
+
133
+ __all__ = ["Generate_Image", "build_interface"]