soupstick
Fix: Remove conflicting gradio-client version constraint
f96d29c
raw
history blame
6.79 kB
import gradio as gr
import torch
import json
from PIL import Image
from transformers import AutoProcessor, Qwen2VLForConditionalGeneration
from peft import PeftModel
import warnings
warnings.filterwarnings("ignore")
# Model configuration
BASE_MODEL = "Qwen/Qwen2-VL-7B-Instruct"
ADAPTER = "soupstick/qwen2vl-amazon-ft-lora"
# Global variables for lazy loading
model = None
processor = None
def load_model():
"""Load model and processor with CPU optimization"""
global model, processor
if model is None:
print("⏳ Loading model (CPU mode)...")
try:
# Force CPU usage and optimize for memory
model = Qwen2VLForConditionalGeneration.from_pretrained(
BASE_MODEL,
device_map="cpu",
torch_dtype=torch.float32, # Use float32 for CPU
trust_remote_code=True,
low_cpu_mem_usage=True,
use_cache=True
)
# Load LoRA adapter
print("⏳ Loading LoRA adapter...")
model = PeftModel.from_pretrained(model, ADAPTER)
# Load processor
processor = AutoProcessor.from_pretrained(
BASE_MODEL,
trust_remote_code=True
)
print("βœ… Model loaded successfully!")
except Exception as e:
print(f"❌ Error loading model: {e}")
return False
return True
def generate_listing(image, prompt="Generate Amazon listing."):
"""Generate Amazon listing from image"""
if image is None:
return "⚠️ Please upload an image."
# Load model if not already loaded
if not load_model():
return "❌ Error: Could not load model. Please try again."
try:
# Resize image to reduce memory usage
if image.size[0] > 512 or image.size[1] > 512:
image.thumbnail((512, 512), Image.Resampling.LANCZOS)
# Prepare chat messages
messages = [{
"role": "user",
"content": [
{"type": "image", "image": image},
{"type": "text", "text": prompt}
],
}]
# Apply chat template
text = processor.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
# Process inputs
inputs = processor(
text=text,
images=image,
return_tensors="pt"
)
# Generate with conservative settings for CPU
print("⏳ Generating listing...")
with torch.no_grad():
generated_ids = model.generate(
**inputs,
max_new_tokens=256, # Reduced for CPU
do_sample=True,
temperature=0.7,
top_p=0.8,
pad_token_id=processor.tokenizer.eos_token_id
)
# Decode output
generated_ids_trimmed = [
out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
]
output_text = processor.batch_decode(
generated_ids_trimmed,
skip_special_tokens=True,
clean_up_tokenization_spaces=False
)[0]
return output_text
except Exception as e:
return f"❌ Error generating listing: {str(e)}"
def format_example_output():
"""Show example of expected output format"""
example = {
"title": "Premium Wireless Bluetooth Headphones with Noise Cancellation",
"bullet_points": [
"β€’ Advanced noise cancellation technology for immersive audio experience",
"β€’ 30-hour battery life with quick charge feature",
"β€’ Premium comfort design with soft ear cushions",
"β€’ Universal compatibility with all Bluetooth devices",
"β€’ Built-in microphone for crystal clear calls"
],
"description": "Experience premium audio quality with these advanced wireless headphones...",
"keywords": "wireless headphones, bluetooth, noise cancelling, premium audio",
"category": "Electronics > Audio > Headphones"
}
return json.dumps(example, indent=2)
# Gradio Interface
def create_interface():
with gr.Blocks(theme=gr.themes.Soft(), title="Amazon Listing Generator") as demo:
gr.Markdown("""
# πŸ›’ Qwen2-VL Amazon Listing Generator (LoRA)
Upload a product image and generate an Amazon-style listing with title, bullet points, description, keywords, and category.
**Model**: [soupstick/qwen2vl-amazon-ft-lora](https://huggingface.co/soupstick/qwen2vl-amazon-ft-lora) (Qwen2-VL-7B + LoRA)
""")
with gr.Row():
with gr.Column():
image_input = gr.Image(
type="pil",
label="πŸ“Έ Upload Product Image",
height=300
)
prompt_input = gr.Textbox(
label="πŸ“ Instruction (Optional)",
value="Generate Amazon listing.",
placeholder="Enter custom instruction or use default",
lines=2
)
generate_btn = gr.Button(
"πŸš€ Generate Listing",
variant="primary",
size="lg"
)
with gr.Column():
output_text = gr.Textbox(
label="πŸ“‹ Generated Listing",
lines=15,
placeholder="Upload an image and click 'Generate Listing' to see results..."
)
# Example section
with gr.Accordion("πŸ“‹ Expected Output Format", open=False):
gr.Code(
format_example_output(),
language="json",
label="Example JSON Structure"
)
# Event handler
generate_btn.click(
fn=generate_listing,
inputs=[image_input, prompt_input],
outputs=output_text
)
# Footer
gr.Markdown("""
---
**⚠️ Note**: This demo runs on CPU which may take 1-2 minutes per generation.
For faster inference, consider upgrading to GPU hardware.
**πŸ”— Links**: [Model Card](https://huggingface.co/soupstick/qwen2vl-amazon-ft-lora) | [Base Model](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct)
""")
return demo
if __name__ == "__main__":
demo = create_interface()
demo.launch(share=True)