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! ๐")
|