Ovis-Image-7B / app.py
akhaliq's picture
akhaliq HF Staff
Upload folder using huggingface_hub
63b9ac2 verified
raw
history blame
11.1 kB
import gradio as gr
import torch
import spaces
from diffusers import OvisImagePipeline
# Load the model at startup
pipe = OvisImagePipeline.from_pretrained(
"AIDC-AI/Ovis-Image-7B",
torch_dtype=torch.bfloat16
)
pipe.to("cuda")
@spaces.GPU(duration=120)
def generate_image(
prompt: str,
negative_prompt: str,
num_inference_steps: int,
true_cfg_scale: float,
progress=gr.Progress(track_tqdm=True)
):
if not prompt.strip():
raise gr.Error("Please enter a prompt to generate an image.")
image = pipe(
prompt=prompt,
negative_prompt=negative_prompt if negative_prompt.strip() else "",
num_inference_steps=int(num_inference_steps),
true_cfg_scale=true_cfg_scale
).images[0]
return image
# Apple-inspired CSS
apple_css = """
/* Apple-style design system */
@import url('https://fonts.googleapis.com/css2?family=SF+Pro+Display:wght@300;400;500;600;700&family=SF+Pro+Text:wght@400;500;600&display=swap');
:root {
--apple-blue: #0071e3;
--apple-blue-hover: #0077ED;
--apple-gray-1: #f5f5f7;
--apple-gray-2: #e8e8ed;
--apple-gray-3: #d2d2d7;
--apple-gray-4: #86868b;
--apple-gray-5: #1d1d1f;
--apple-white: #ffffff;
--apple-black: #000000;
--apple-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
--apple-shadow-hover: 0 8px 32px rgba(0, 0, 0, 0.12);
--apple-radius: 12px;
--apple-radius-lg: 18px;
--apple-transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
}
/* Base styles */
.gradio-container {
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
background: linear-gradient(180deg, var(--apple-gray-1) 0%, var(--apple-white) 100%) !important;
min-height: 100vh;
max-width: 1200px !important;
margin: 0 auto !important;
padding: 40px 20px !important;
}
/* Header styling */
.header-container {
text-align: center;
padding: 60px 20px 40px;
margin-bottom: 40px;
}
.header-container h1 {
font-size: 56px !important;
font-weight: 600 !important;
letter-spacing: -0.02em !important;
color: var(--apple-gray-5) !important;
margin-bottom: 16px !important;
line-height: 1.1 !important;
}
.header-container p {
font-size: 21px !important;
font-weight: 400 !important;
color: var(--apple-gray-4) !important;
max-width: 600px;
margin: 0 auto !important;
line-height: 1.5 !important;
}
.header-container a {
color: var(--apple-blue) !important;
text-decoration: none !important;
transition: var(--apple-transition);
}
.header-container a:hover {
text-decoration: underline !important;
}
/* Card-like containers */
.input-section, .output-section {
background: var(--apple-white) !important;
border-radius: var(--apple-radius-lg) !important;
padding: 32px !important;
box-shadow: var(--apple-shadow) !important;
border: 1px solid var(--apple-gray-2) !important;
transition: var(--apple-transition);
}
.input-section:hover, .output-section:hover {
box-shadow: var(--apple-shadow-hover) !important;
}
/* Textbox styling */
.gradio-textbox textarea, .gradio-textbox input {
font-family: inherit !important;
font-size: 17px !important;
border: 2px solid var(--apple-gray-2) !important;
border-radius: var(--apple-radius) !important;
padding: 16px !important;
background: var(--apple-gray-1) !important;
transition: var(--apple-transition);
color: var(--apple-gray-5) !important;
}
.gradio-textbox textarea:focus, .gradio-textbox input:focus {
border-color: var(--apple-blue) !important;
background: var(--apple-white) !important;
outline: none !important;
box-shadow: 0 0 0 4px rgba(0, 113, 227, 0.15) !important;
}
.gradio-textbox label {
font-size: 14px !important;
font-weight: 600 !important;
color: var(--apple-gray-5) !important;
letter-spacing: -0.01em !important;
margin-bottom: 8px !important;
}
/* Slider styling */
.gradio-slider input[type="range"] {
height: 6px !important;
background: var(--apple-gray-2) !important;
border-radius: 3px !important;
}
.gradio-slider input[type="range"]::-webkit-slider-thumb {
width: 22px !important;
height: 22px !important;
background: var(--apple-white) !important;
border: 2px solid var(--apple-gray-3) !important;
border-radius: 50% !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
cursor: pointer !important;
transition: var(--apple-transition);
}
.gradio-slider input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.1);
border-color: var(--apple-blue) !important;
}
.gradio-slider label {
font-size: 14px !important;
font-weight: 600 !important;
color: var(--apple-gray-5) !important;
}
.gradio-slider .wrap {
background: transparent !important;
}
/* Button styling */
.gradio-button {
font-family: inherit !important;
font-size: 17px !important;
font-weight: 500 !important;
border-radius: 980px !important;
padding: 16px 32px !important;
transition: var(--apple-transition);
border: none !important;
cursor: pointer !important;
letter-spacing: -0.01em !important;
}
.gradio-button.primary {
background: var(--apple-blue) !important;
color: var(--apple-white) !important;
}
.gradio-button.primary:hover {
background: var(--apple-blue-hover) !important;
transform: scale(1.02);
}
.gradio-button.primary:active {
transform: scale(0.98);
}
.gradio-button.secondary {
background: var(--apple-gray-1) !important;
color: var(--apple-blue) !important;
}
.gradio-button.secondary:hover {
background: var(--apple-gray-2) !important;
}
/* Image output styling */
.gradio-image {
border-radius: var(--apple-radius-lg) !important;
overflow: hidden !important;
background: var(--apple-gray-1) !important;
border: 1px solid var(--apple-gray-2) !important;
}
.gradio-image img {
border-radius: var(--apple-radius) !important;
}
/* Row and column spacing */
.gradio-row {
gap: 16px !important;
}
.gradio-column {
gap: 16px !important;
}
/* Section labels */
.section-label {
font-size: 13px !important;
font-weight: 600 !important;
color: var(--apple-gray-4) !important;
text-transform: uppercase !important;
letter-spacing: 0.02em !important;
margin-bottom: 16px !important;
}
/* Slider container */
.slider-row {
background: var(--apple-gray-1) !important;
border-radius: var(--apple-radius) !important;
padding: 20px !important;
margin-top: 8px !important;
}
/* Footer link styling */
.built-with {
text-align: center;
padding: 40px 20px;
color: var(--apple-gray-4);
font-size: 14px;
}
.built-with a {
color: var(--apple-blue) !important;
text-decoration: none !important;
}
.built-with a:hover {
text-decoration: underline !important;
}
/* Progress bar */
.progress-bar {
background: var(--apple-gray-2) !important;
border-radius: 4px !important;
}
.progress-bar > div {
background: linear-gradient(90deg, var(--apple-blue), #34C759) !important;
border-radius: 4px !important;
}
/* Placeholder text */
::placeholder {
color: var(--apple-gray-4) !important;
opacity: 1 !important;
}
/* Remove default borders and shadows */
.block {
border: none !important;
box-shadow: none !important;
}
/* Group styling */
.group {
background: var(--apple-white) !important;
border-radius: var(--apple-radius-lg) !important;
padding: 24px !important;
box-shadow: var(--apple-shadow) !important;
}
/* Accordion styling */
.gradio-accordion {
border: 1px solid var(--apple-gray-2) !important;
border-radius: var(--apple-radius) !important;
overflow: hidden !important;
}
.gradio-accordion > button {
background: var(--apple-gray-1) !important;
font-weight: 500 !important;
}
/* Hide default footer items we don't want */
footer {
opacity: 0.7;
}
"""
with gr.Blocks(
title="OVIS Image Generator",
css=apple_css
) as demo:
# Header
gr.HTML("""
<div class="header-container">
<h1>OVIS Image</h1>
<p>Create stunning images with OVIS-Image-7B. Simply describe what you imagine.</p>
<p style="margin-top: 12px; font-size: 14px;">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
</p>
</div>
""")
with gr.Row():
# Left column - Input
with gr.Column(scale=1, elem_classes="input-section"):
gr.HTML('<div class="section-label">Create</div>')
prompt = gr.Textbox(
label="Prompt",
placeholder="Describe the image you want to create...",
lines=4,
elem_id="prompt-input"
)
negative_prompt = gr.Textbox(
label="Negative Prompt",
placeholder="What to avoid (optional)...",
lines=2
)
gr.HTML('<div class="section-label" style="margin-top: 24px;">Settings</div>')
with gr.Group(elem_classes="slider-row"):
num_steps = gr.Slider(
label="Inference Steps",
minimum=10,
maximum=100,
value=50,
step=5,
info="More steps = higher quality, slower generation"
)
cfg_scale = gr.Slider(
label="CFG Scale",
minimum=1.0,
maximum=15.0,
value=5.0,
step=0.5,
info="How closely to follow your prompt"
)
generate_btn = gr.Button(
"Generate Image",
variant="primary",
size="lg",
elem_id="generate-btn"
)
# Right column - Output
with gr.Column(scale=1, elem_classes="output-section"):
gr.HTML('<div class="section-label">Result</div>')
output_image = gr.Image(
label="Generated Image",
type="pil",
elem_id="output-image",
height=512
)
# Event handlers
generate_btn.click(
fn=generate_image,
inputs=[prompt, negative_prompt, num_steps, cfg_scale],
outputs=output_image,
api_visibility="public"
)
prompt.submit(
fn=generate_image,
inputs=[prompt, negative_prompt, num_steps, cfg_scale],
outputs=output_image,
api_visibility="public"
)
if __name__ == "__main__":
demo.launch(
footer_links=[
{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}
]
)