VcRlAgent's picture
Rate Limit and Model Warning
ad5f092
Raw History Blame Contribute Delete
9.92 kB
import gradio as gr
import yaml
import torch
from PIL import Image
from rembg import remove
from rate_limiter import RateLimiter
from replicate_handler import ReplicateHandler
# ------------------------------------------
# Load Configuration
# ------------------------------------------
with open("config.yaml", "r") as f:
config = yaml.safe_load(f)
# Initialize modules
rate_limiter = RateLimiter(
session_file=config["rate_limit"]["session_file"],
daily_limit=config["rate_limit"]["default_daily_limit"],
dev_daily_limit=config["rate_limit"]["dev_daily_limit"]
)
replicate_handler = ReplicateHandler(
model=config["replicate"]["model"],
default_settings=config["replicate"]["default_settings"]
)
# ------------------------------------------
# Core Functions
# ------------------------------------------
def remove_background(img: Image.Image) -> Image.Image:
"""Remove background from image"""
if img is None:
raise gr.Error("Please upload an image first")
return remove(img)
def generate_headshot(
img: Image.Image,
headshot_style: str,
use_advanced: bool,
cfg: float,
steps: int,
denoise: float,
request: gr.Request
) -> Image.Image:
"""Generate professional headshot with selected style"""
# Check rate limit
allowed, remaining, reset_time = rate_limiter.check_limit(request)
if not allowed:
raise gr.Error(rate_limiter.get_limit_message(remaining, reset_time))
if img is None:
raise gr.Error("Please upload an image first")
# Get prompt from config
style_config = config["headshots"][headshot_style]
prompt = style_config["prompt"]
negative_prompt = style_config["negative"]
# Prepare settings
custom_settings = None
if use_advanced:
custom_settings = {
"cfg": cfg,
"steps": steps,
"denoise": denoise
}
# Generate
try:
result = replicate_handler.generate(
input_image=img,
prompt=prompt,
negative_prompt=negative_prompt,
custom_settings=custom_settings
)
# Increment usage
rate_limiter.increment(request)
return result
except Exception as e:
raise gr.Error(f"Generation failed: {str(e)}")
def generate_scene(
img: Image.Image,
scene_style: str,
use_advanced: bool,
cfg: float,
steps: int,
denoise: float,
request: gr.Request
) -> Image.Image:
"""Generate scene change with selected style"""
# Check rate limit
allowed, remaining, reset_time = rate_limiter.check_limit(request)
if not allowed:
raise gr.Error(rate_limiter.get_limit_message(remaining, reset_time))
if img is None:
raise gr.Error("Please upload an image first")
# Get prompt from config
style_config = config["scenes"][scene_style]
prompt = style_config["prompt"]
negative_prompt = style_config["negative"]
# Prepare settings
custom_settings = None
if use_advanced:
custom_settings = {
"cfg": cfg,
"steps": steps,
"denoise": denoise
}
# Generate
try:
result = replicate_handler.generate(
input_image=img,
prompt=prompt,
negative_prompt=negative_prompt,
custom_settings=custom_settings
)
# Increment usage
rate_limiter.increment(request)
return result
except Exception as e:
raise gr.Error(f"Generation failed: {str(e)}")
def get_rate_limit_status(request: gr.Request) -> str:
"""Get current rate limit status"""
allowed, remaining, reset_time = rate_limiter.check_limit(request)
return rate_limiter.get_limit_message(remaining, reset_time)
# ------------------------------------------
# Gradio Interface
# ------------------------------------------
with gr.Blocks(theme=gr.themes.Soft(), title="FaceForge AI") as demo:
gr.Markdown(
"""
# 🎨 FaceForge AI
### AI-Powered Professional Photo Generator
Upload your photo and transform it into professional headshots or place yourself in different scenes.
"""
)
# Rate limit status
rate_status = gr.Textbox(
label="πŸ“Š Usage Status",
interactive=False,
value="Loading..."
)
with gr.Row():
# Left Column - Input
with gr.Column(scale=1):
input_image = gr.Image(type="pil", label="πŸ“· Upload Your Photo")
gr.Markdown("### βš™οΈ Advanced Settings (Optional)")
use_advanced = gr.Checkbox(
label="Enable Advanced Settings",
value=False
)
with gr.Group(visible=True) as advanced_group:
cfg_slider = gr.Slider(
label="πŸŽ›οΈ CFG Scale",
minimum=config["replicate"]["advanced_ranges"]["cfg"]["min"],
maximum=config["replicate"]["advanced_ranges"]["cfg"]["max"],
value=config["replicate"]["default_settings"]["cfg"],
step=config["replicate"]["advanced_ranges"]["cfg"]["step"]
)
steps_slider = gr.Slider(
label="πŸ”„ Steps",
minimum=config["replicate"]["advanced_ranges"]["steps"]["min"],
maximum=config["replicate"]["advanced_ranges"]["steps"]["max"],
value=config["replicate"]["default_settings"]["steps"],
step=config["replicate"]["advanced_ranges"]["steps"]["step"]
)
denoise_slider = gr.Slider(
label="✨ Denoise",
minimum=config["replicate"]["advanced_ranges"]["denoise"]["min"],
maximum=config["replicate"]["advanced_ranges"]["denoise"]["max"],
value=config["replicate"]["default_settings"]["denoise"],
step=config["replicate"]["advanced_ranges"]["denoise"]["step"]
)
# Toggle visibility of advanced settings
use_advanced.change(
fn=lambda x: gr.update(visible=x),
inputs=[use_advanced],
outputs=[advanced_group]
)
# Right Column - Outputs
with gr.Column(scale=1):
# Background Remover Section
gr.Markdown("### 🎭 Background Remover")
output_bg_removed = gr.Image(label="Background Removed", type="pil")
btn_bg_remove = gr.Button("πŸ—‘οΈ Remove Background", variant="secondary")
gr.Markdown("---")
# Professional Headshots Section
gr.Markdown("### πŸ’Ό Professional Headshots")
headshot_style = gr.Dropdown(
label="Choose Headshot Style",
choices=list(config["headshots"].keys()),
value=list(config["headshots"].keys())[0]
)
output_headshot = gr.Image(label="Professional Headshot", type="pil")
btn_headshot = gr.Button("πŸ“Έ Generate Headshot", variant="primary")
gr.Markdown("---")
# Scene Changer Section
gr.Markdown("### 🌍 Scene Changer")
scene_style = gr.Dropdown(
label="Choose Scene",
choices=list(config["scenes"].keys()),
value=list(config["scenes"].keys())[0]
)
output_scene = gr.Image(label="Scene Changed", type="pil")
btn_scene = gr.Button("🎬 Change Scene", variant="primary")
# Button Actions
btn_bg_remove.click(
fn=remove_background,
inputs=[input_image],
outputs=[output_bg_removed]
)
btn_headshot.click(
fn=generate_headshot,
inputs=[
input_image,
headshot_style,
use_advanced,
cfg_slider,
steps_slider,
denoise_slider
],
outputs=[output_headshot]
)
btn_scene.click(
fn=generate_scene,
inputs=[
input_image,
scene_style,
use_advanced,
cfg_slider,
steps_slider,
denoise_slider
],
outputs=[output_scene]
)
# Update rate limit status on load and after each generation
demo.load(fn=get_rate_limit_status, inputs=None, outputs=[rate_status])
btn_headshot.click(fn=get_rate_limit_status, inputs=None, outputs=[rate_status])
btn_scene.click(fn=get_rate_limit_status, inputs=None, outputs=[rate_status])
gr.Markdown(
"""
---
### ✨ Features
- 🎭 **Background Remover**: Clean background removal for any image
- πŸ’Ό **Professional Headshots**: Studio-quality headshots with multiple styles
- 🌍 **Scene Changer**: Place yourself in different environments
- ⚑ **AI-Powered**: InstantID technology for identity preservation
- πŸ”’ **Rate Limited**: Fair usage with daily limits
"""
)
gr.Markdown(
"""
---
### ⚠️ Notice
- This is a **personal experimental project** and has undergone **limited testing**. Please use with caution.
- Although **InstantID** is designed to preserve identity, outputs may vary based on **prompts, model weights, and other influencing factors**.
Β© 2025 Vijay S. Chaudhari | Powered by Replicate, InstantID and HuggingFace πŸš€
"""
)
# Launch
if __name__ == "__main__":
demo.queue(max_size=20)
demo.launch()