Update app.py
Browse files
app.py
CHANGED
|
@@ -5,12 +5,11 @@ import base64
|
|
| 5 |
import streamlit as st
|
| 6 |
import pandas as pd
|
| 7 |
import torch
|
| 8 |
-
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 9 |
from torch.utils.data import Dataset, DataLoader
|
| 10 |
import csv
|
| 11 |
import time
|
| 12 |
from dataclasses import dataclass
|
| 13 |
-
from typing import Optional
|
| 14 |
import zipfile
|
| 15 |
import math
|
| 16 |
from PIL import Image
|
|
@@ -18,7 +17,7 @@ import random
|
|
| 18 |
import logging
|
| 19 |
import numpy as np
|
| 20 |
import cv2
|
| 21 |
-
from diffusers import DiffusionPipeline
|
| 22 |
|
| 23 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
| 24 |
logger = logging.getLogger(__name__)
|
|
@@ -42,7 +41,6 @@ st.set_page_config(
|
|
| 42 |
}
|
| 43 |
)
|
| 44 |
|
| 45 |
-
# Session State Setup ๐ - Persistent playground for our tiny titans!
|
| 46 |
if 'captured_images' not in st.session_state:
|
| 47 |
st.session_state['captured_images'] = []
|
| 48 |
if 'cv_builder' not in st.session_state:
|
|
@@ -62,7 +60,6 @@ class DiffusionConfig:
|
|
| 62 |
def model_path(self):
|
| 63 |
return f"diffusion_models/{self.name}"
|
| 64 |
|
| 65 |
-
# Datasets ๐ฒ - Feeding our titans with pixel snacks and text treats!
|
| 66 |
class DiffusionDataset(Dataset):
|
| 67 |
"""Pixel party platter ๐ - Images and text for diffusion delight!"""
|
| 68 |
def __init__(self, images, texts):
|
|
@@ -82,8 +79,7 @@ class MicroDiffusionBuilder:
|
|
| 82 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 83 |
try:
|
| 84 |
with st.spinner(f"Loading {model_path}... โณ (Tiny titan powering up!)"):
|
| 85 |
-
|
| 86 |
-
self.pipeline = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", custom_pipeline="small_diffusion")
|
| 87 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 88 |
if config:
|
| 89 |
self.config = config
|
|
@@ -154,7 +150,7 @@ class LatentDiffusionBuilder:
|
|
| 154 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 155 |
try:
|
| 156 |
with st.spinner(f"Loading {model_path}... โณ (Latent titan rising!)"):
|
| 157 |
-
self.pipeline = DiffusionPipeline.from_pretrained(model_path,
|
| 158 |
self.pipeline.unet = torch.nn.Sequential(*list(self.pipeline.unet.children())[:2]) # Scale down U-Net
|
| 159 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 160 |
if config:
|
|
@@ -226,7 +222,7 @@ class FluxDiffusionBuilder:
|
|
| 226 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 227 |
try:
|
| 228 |
with st.spinner(f"Loading {model_path}... โณ (Flux titan charging!)"):
|
| 229 |
-
self.pipeline = DiffusionPipeline.from_pretrained(model_path,
|
| 230 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 231 |
if config:
|
| 232 |
self.config = config
|
|
@@ -348,11 +344,11 @@ def update_gallery():
|
|
| 348 |
st.markdown(get_download_link(file, "image/png", "Download Snap ๐ธ"), unsafe_allow_html=True)
|
| 349 |
|
| 350 |
def get_available_video_devices():
|
| 351 |
-
"""Camera roll call ๐ฅ - Whoโs ready to shine?"""
|
| 352 |
-
video_devices = [f"Camera {i} ๐ฅ" for i in range(6)] # 6 cams
|
| 353 |
try:
|
| 354 |
detected = []
|
| 355 |
-
for i in range(
|
| 356 |
cap = cv2.VideoCapture(i, cv2.CAP_V4L2)
|
| 357 |
if not cap.isOpened():
|
| 358 |
cap = cv2.VideoCapture(i)
|
|
@@ -361,9 +357,11 @@ def get_available_video_devices():
|
|
| 361 |
logger.info(f"Detected camera at index {i}")
|
| 362 |
cap.release()
|
| 363 |
if detected:
|
| 364 |
-
video_devices = detected
|
|
|
|
|
|
|
| 365 |
except Exception as e:
|
| 366 |
-
logger.error(f"Error detecting cameras: {str(e)}")
|
| 367 |
return video_devices
|
| 368 |
|
| 369 |
st.title("SFT Tiny Titans ๐ (Small Diffusion Delight!)")
|
|
@@ -445,7 +443,7 @@ with tab1:
|
|
| 445 |
st.header("Build Titan ๐ฑ")
|
| 446 |
model_type = st.selectbox("Diffusion Type", ["Micro Diffusion", "Latent Diffusion", "FLUX.1 Distilled"], key="build_type")
|
| 447 |
base_model = st.selectbox("Select Tiny Model",
|
| 448 |
-
["
|
| 449 |
model_name = st.text_input("Model Name", f"tiny-titan-{int(time.time())}")
|
| 450 |
if st.button("Download Model โฌ๏ธ"):
|
| 451 |
config = DiffusionConfig(name=model_name, base_model=base_model, size="small")
|
|
@@ -469,7 +467,6 @@ with tab2:
|
|
| 469 |
st.write(f"๐ Detected Cameras: {', '.join(video_devices)}")
|
| 470 |
st.info("Switch cams in your browser settings (e.g., Chrome > Privacy > Camera) since Iโm a browser star! ๐")
|
| 471 |
|
| 472 |
-
# Camera 0 Settings
|
| 473 |
st.subheader("Camera 0 ๐ฌ - Lights, Camera, Action!")
|
| 474 |
cam0_cols = st.columns(4)
|
| 475 |
with cam0_cols[0]:
|
|
@@ -481,7 +478,6 @@ with tab2:
|
|
| 481 |
with cam0_cols[3]:
|
| 482 |
cam0_vis = st.selectbox("Show ๐ผ๏ธ", ["visible", "hidden", "collapsed"], index=0, key="cam0_vis", help="Label vibes: Visible, Sneaky, or Gone!")
|
| 483 |
|
| 484 |
-
# Camera 1 Settings
|
| 485 |
st.subheader("Camera 1 ๐ฅ - Roll the Film!")
|
| 486 |
cam1_cols = st.columns(4)
|
| 487 |
with cam1_cols[0]:
|
|
@@ -493,7 +489,6 @@ with tab2:
|
|
| 493 |
with cam1_cols[3]:
|
| 494 |
cam1_vis = st.selectbox("Show ๐ผ๏ธ", ["visible", "hidden", "collapsed"], index=0, key="cam1_vis", help="Label style: Show it, Hide it, Poof!")
|
| 495 |
|
| 496 |
-
# Capture Widgets
|
| 497 |
cols = st.columns(2)
|
| 498 |
with cols[0]:
|
| 499 |
st.subheader(f"Camera 0 ({cam0_device}) ๐ฌ")
|
|
@@ -539,7 +534,6 @@ with tab3:
|
|
| 539 |
else:
|
| 540 |
captured_images = get_gallery_files(["png"])
|
| 541 |
if len(captured_images) >= 2:
|
| 542 |
-
# Use Case 1: Denoising (Micro Diffusion)
|
| 543 |
st.subheader("Use Case 1: Denoise Snapshots ๐")
|
| 544 |
denoising_data = [{"image": img, "text": f"Denoised {os.path.basename(img).split('-')[4]} snap"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 545 |
denoising_edited = st.data_editor(pd.DataFrame(denoising_data), num_rows="dynamic", help="Craft denoising pairs! ๐")
|
|
@@ -564,7 +558,6 @@ with tab3:
|
|
| 564 |
writer.writerow([row["image"], row["text"]])
|
| 565 |
st.markdown(get_download_link(denoising_csv, "text/csv", "Download Denoising CSV ๐"), unsafe_allow_html=True)
|
| 566 |
|
| 567 |
-
# Use Case 2: Stylization (Latent Diffusion)
|
| 568 |
st.subheader("Use Case 2: Stylize Snapshots ๐จ")
|
| 569 |
stylize_data = [{"image": img, "text": f"Neon {os.path.basename(img).split('-')[4]} style"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 570 |
stylize_edited = st.data_editor(pd.DataFrame(stylize_data), num_rows="dynamic", help="Craft stylized pairs! ๐จ")
|
|
@@ -588,7 +581,6 @@ with tab3:
|
|
| 588 |
f.write(f"- `{row['image']}`: {row['text']}\n")
|
| 589 |
st.markdown(get_download_link(stylize_md, "text/markdown", "Download Stylization MD ๐"), unsafe_allow_html=True)
|
| 590 |
|
| 591 |
-
# Use Case 3: Multi-Angle Generation (FLUX.1)
|
| 592 |
st.subheader("Use Case 3: Multi-Angle Snapshots ๐")
|
| 593 |
multiangle_data = [{"image": img, "text": f"View from {os.path.basename(img).split('-')[4]}"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 594 |
multiangle_edited = st.data_editor(pd.DataFrame(multiangle_data), num_rows="dynamic", help="Craft multi-angle pairs! ๐")
|
|
|
|
| 5 |
import streamlit as st
|
| 6 |
import pandas as pd
|
| 7 |
import torch
|
|
|
|
| 8 |
from torch.utils.data import Dataset, DataLoader
|
| 9 |
import csv
|
| 10 |
import time
|
| 11 |
from dataclasses import dataclass
|
| 12 |
+
from typing import Optional
|
| 13 |
import zipfile
|
| 14 |
import math
|
| 15 |
from PIL import Image
|
|
|
|
| 17 |
import logging
|
| 18 |
import numpy as np
|
| 19 |
import cv2
|
| 20 |
+
from diffusers import DiffusionPipeline
|
| 21 |
|
| 22 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
| 23 |
logger = logging.getLogger(__name__)
|
|
|
|
| 41 |
}
|
| 42 |
)
|
| 43 |
|
|
|
|
| 44 |
if 'captured_images' not in st.session_state:
|
| 45 |
st.session_state['captured_images'] = []
|
| 46 |
if 'cv_builder' not in st.session_state:
|
|
|
|
| 60 |
def model_path(self):
|
| 61 |
return f"diffusion_models/{self.name}"
|
| 62 |
|
|
|
|
| 63 |
class DiffusionDataset(Dataset):
|
| 64 |
"""Pixel party platter ๐ - Images and text for diffusion delight!"""
|
| 65 |
def __init__(self, images, texts):
|
|
|
|
| 79 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 80 |
try:
|
| 81 |
with st.spinner(f"Loading {model_path}... โณ (Tiny titan powering up!)"):
|
| 82 |
+
self.pipeline = DiffusionPipeline.from_pretrained(model_path, low_cpu_mem_usage=True)
|
|
|
|
| 83 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 84 |
if config:
|
| 85 |
self.config = config
|
|
|
|
| 150 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 151 |
try:
|
| 152 |
with st.spinner(f"Loading {model_path}... โณ (Latent titan rising!)"):
|
| 153 |
+
self.pipeline = DiffusionPipeline.from_pretrained(model_path, low_cpu_mem_usage=True)
|
| 154 |
self.pipeline.unet = torch.nn.Sequential(*list(self.pipeline.unet.children())[:2]) # Scale down U-Net
|
| 155 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 156 |
if config:
|
|
|
|
| 222 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
| 223 |
try:
|
| 224 |
with st.spinner(f"Loading {model_path}... โณ (Flux titan charging!)"):
|
| 225 |
+
self.pipeline = DiffusionPipeline.from_pretrained(model_path, low_cpu_mem_usage=True)
|
| 226 |
self.pipeline.to("cuda" if torch.cuda.is_available() else "cpu")
|
| 227 |
if config:
|
| 228 |
self.config = config
|
|
|
|
| 344 |
st.markdown(get_download_link(file, "image/png", "Download Snap ๐ธ"), unsafe_allow_html=True)
|
| 345 |
|
| 346 |
def get_available_video_devices():
|
| 347 |
+
"""Camera roll call ๐ฅ - Whoโs ready to shine? Fallback if OpenCV flops!"""
|
| 348 |
+
video_devices = [f"Camera {i} ๐ฅ" for i in range(6)] # Default to 6 cams
|
| 349 |
try:
|
| 350 |
detected = []
|
| 351 |
+
for i in range(6): # Limit to 6 as per your setup
|
| 352 |
cap = cv2.VideoCapture(i, cv2.CAP_V4L2)
|
| 353 |
if not cap.isOpened():
|
| 354 |
cap = cv2.VideoCapture(i)
|
|
|
|
| 357 |
logger.info(f"Detected camera at index {i}")
|
| 358 |
cap.release()
|
| 359 |
if detected:
|
| 360 |
+
video_devices = detected
|
| 361 |
+
else:
|
| 362 |
+
logger.warning("No cameras detected by OpenCV; using defaults")
|
| 363 |
except Exception as e:
|
| 364 |
+
logger.error(f"Error detecting cameras: {str(e)} - Falling back to defaults")
|
| 365 |
return video_devices
|
| 366 |
|
| 367 |
st.title("SFT Tiny Titans ๐ (Small Diffusion Delight!)")
|
|
|
|
| 443 |
st.header("Build Titan ๐ฑ")
|
| 444 |
model_type = st.selectbox("Diffusion Type", ["Micro Diffusion", "Latent Diffusion", "FLUX.1 Distilled"], key="build_type")
|
| 445 |
base_model = st.selectbox("Select Tiny Model",
|
| 446 |
+
["CompVis/ldm-text2im-large-256" if model_type == "Micro Diffusion" else "runwayml/stable-diffusion-v1-5" if model_type == "Latent Diffusion" else "black-forest-labs/flux.1-distilled"])
|
| 447 |
model_name = st.text_input("Model Name", f"tiny-titan-{int(time.time())}")
|
| 448 |
if st.button("Download Model โฌ๏ธ"):
|
| 449 |
config = DiffusionConfig(name=model_name, base_model=base_model, size="small")
|
|
|
|
| 467 |
st.write(f"๐ Detected Cameras: {', '.join(video_devices)}")
|
| 468 |
st.info("Switch cams in your browser settings (e.g., Chrome > Privacy > Camera) since Iโm a browser star! ๐")
|
| 469 |
|
|
|
|
| 470 |
st.subheader("Camera 0 ๐ฌ - Lights, Camera, Action!")
|
| 471 |
cam0_cols = st.columns(4)
|
| 472 |
with cam0_cols[0]:
|
|
|
|
| 478 |
with cam0_cols[3]:
|
| 479 |
cam0_vis = st.selectbox("Show ๐ผ๏ธ", ["visible", "hidden", "collapsed"], index=0, key="cam0_vis", help="Label vibes: Visible, Sneaky, or Gone!")
|
| 480 |
|
|
|
|
| 481 |
st.subheader("Camera 1 ๐ฅ - Roll the Film!")
|
| 482 |
cam1_cols = st.columns(4)
|
| 483 |
with cam1_cols[0]:
|
|
|
|
| 489 |
with cam1_cols[3]:
|
| 490 |
cam1_vis = st.selectbox("Show ๐ผ๏ธ", ["visible", "hidden", "collapsed"], index=0, key="cam1_vis", help="Label style: Show it, Hide it, Poof!")
|
| 491 |
|
|
|
|
| 492 |
cols = st.columns(2)
|
| 493 |
with cols[0]:
|
| 494 |
st.subheader(f"Camera 0 ({cam0_device}) ๐ฌ")
|
|
|
|
| 534 |
else:
|
| 535 |
captured_images = get_gallery_files(["png"])
|
| 536 |
if len(captured_images) >= 2:
|
|
|
|
| 537 |
st.subheader("Use Case 1: Denoise Snapshots ๐")
|
| 538 |
denoising_data = [{"image": img, "text": f"Denoised {os.path.basename(img).split('-')[4]} snap"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 539 |
denoising_edited = st.data_editor(pd.DataFrame(denoising_data), num_rows="dynamic", help="Craft denoising pairs! ๐")
|
|
|
|
| 558 |
writer.writerow([row["image"], row["text"]])
|
| 559 |
st.markdown(get_download_link(denoising_csv, "text/csv", "Download Denoising CSV ๐"), unsafe_allow_html=True)
|
| 560 |
|
|
|
|
| 561 |
st.subheader("Use Case 2: Stylize Snapshots ๐จ")
|
| 562 |
stylize_data = [{"image": img, "text": f"Neon {os.path.basename(img).split('-')[4]} style"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 563 |
stylize_edited = st.data_editor(pd.DataFrame(stylize_data), num_rows="dynamic", help="Craft stylized pairs! ๐จ")
|
|
|
|
| 581 |
f.write(f"- `{row['image']}`: {row['text']}\n")
|
| 582 |
st.markdown(get_download_link(stylize_md, "text/markdown", "Download Stylization MD ๐"), unsafe_allow_html=True)
|
| 583 |
|
|
|
|
| 584 |
st.subheader("Use Case 3: Multi-Angle Snapshots ๐")
|
| 585 |
multiangle_data = [{"image": img, "text": f"View from {os.path.basename(img).split('-')[4]}"} for img in captured_images[:min(len(captured_images), 10)]]
|
| 586 |
multiangle_edited = st.data_editor(pd.DataFrame(multiangle_data), num_rows="dynamic", help="Craft multi-angle pairs! ๐")
|