napstablook911 commited on
Commit
2f115cc
·
verified ·
1 Parent(s): 7646e96

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +150 -0
  2. requirements.txt +81 -3
app.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import io
3
+ from PIL import Image
4
+ import soundfile as sf
5
+ import librosa
6
+ import numpy as np
7
+ import torch # Importa torch
8
+ import sys
9
+ sys.setrecursionlimit(2000) # Aumentiamo il limite di ricorsione
10
+
11
+ # --- Configurazione del Dispositivo ---
12
+ # Questo rileva automaticamente se MPS (GPU Apple Silicon) è disponibile
13
+ # Per ora, useremo la CPU come fallback se MPS è problematico per Stable Audio
14
+ device = "mps" if torch.backends.mps.is_available() else "cpu"
15
+ # ******************** MODIFICA QUI: Forza device = "cpu" ********************
16
+ # Per superare i problemi di Stable Audio su MPS con float16/float32
17
+ # FORZA LA CPU PER TUTTI I MODELLI, per semplicità.
18
+ # Se la caption genera velocemente, potremmo tornare indietro e mettere il modello vit_gpt2 su MPS
19
+ device = "cpu"
20
+ # **************************************************************************
21
+ st.write(f"Utilizzo del dispositivo: {device}")
22
+
23
+
24
+ # --- 1. Caricamento dei Modelli AI (spostati qui, fuori dalle funzioni Streamlit) ---
25
+ @st.cache_resource
26
+ def load_models():
27
+ # Caricamento del modello per la captioning (ViT-GPT2)
28
+ from transformers import AutoFeatureExtractor, AutoTokenizer, AutoModelForVision2Seq
29
+ st.write("Caricamento del modello ViT-GPT2 per la captioning dell'immagine...")
30
+
31
+ vit_gpt2_feature_extractor = AutoFeatureExtractor.from_pretrained("nlpconnect/vit-gpt2-image-captioning")
32
+ vit_gpt2_tokenizer = AutoTokenizer.from_pretrained("nlpconnect/vit-gpt2-image-captioning")
33
+
34
+ # Questo modello andrà sulla CPU
35
+ vit_gpt2_model = AutoModelForVision2Seq.from_pretrained("nlpconnect/vit-gpt2-image-captioning").to(device)
36
+
37
+ st.write("Modello ViT-GPT2 caricato.")
38
+
39
+ # Caricamento del modello Text-to-Audio (Stable Audio Open - 1.0)
40
+ from diffusers import DiffusionPipeline
41
+ st.write("Caricamento del modello Stable Audio Open - 1.0 per la generazione del soundscape...")
42
+ # ******************** MODIFICA QUI ********************
43
+ # Assicurati che non ci sia torch_dtype=torch.float16 e che vada sulla CPU
44
+ stable_audio_pipeline = DiffusionPipeline.from_pretrained("stabilityai/stable-audio-open-1.0", force_download=True).to(device)
45
+ # ******************************************************
46
+ st.write("Modello Stable Audio Open 1.0 caricato.")
47
+
48
+ return vit_gpt2_feature_extractor, vit_gpt2_model, vit_gpt2_tokenizer, stable_audio_pipeline
49
+
50
+ # Carica i modelli all'avvio dell'app
51
+ vit_gpt2_feature_extractor, vit_gpt2_model, vit_gpt2_tokenizer, stable_audio_pipeline = load_models()
52
+
53
+
54
+ # --- 2. Funzioni della Pipeline ---
55
+ def generate_image_caption(image_pil):
56
+ pixel_values = vit_gpt2_feature_extractor(images=image_pil.convert("RGB"), return_tensors="pt").pixel_values
57
+ pixel_values = pixel_values.to(device) # Sposta input su CPU
58
+
59
+ # Token di inizio per GPT-2, assicurandosi che sia su CPU
60
+ # Ottieni il decoder_start_token_id dal modello o dal tokenizer
61
+ if hasattr(vit_gpt2_model.config, "decoder_start_token_id"):
62
+ decoder_start_token_id = vit_gpt2_model.config.decoder_start_token_id
63
+ else:
64
+ if vit_gpt2_tokenizer.pad_token_id is not None:
65
+ decoder_start_token_id = vit_gpt2_tokenizer.pad_token_id
66
+ else:
67
+ decoder_start_token_id = 50256 # Default GPT-2 EOS token
68
+
69
+ # Crea un input_ids iniziale con il decoder_start_token_id e spostalo su CPU
70
+ input_ids = torch.ones((1, 1), device=device, dtype=torch.long) * decoder_start_token_id
71
+
72
+
73
+ output_ids = vit_gpt2_model.generate(
74
+ pixel_values=pixel_values,
75
+ input_ids=input_ids,
76
+ max_length=50,
77
+ do_sample=True,
78
+ top_k=50,
79
+ temperature=0.7,
80
+ no_repeat_ngram_size=2,
81
+ early_stopping=True
82
+ )
83
+ caption = vit_gpt2_tokenizer.decode(output_ids[0], skip_special_tokens=True)
84
+ return caption
85
+
86
+
87
+ def generate_soundscape_from_caption(caption: str, duration_seconds: int = 10):
88
+ st.write(f"Generazione soundscape per: '{caption}' (durata: {duration_seconds}s)")
89
+ with st.spinner("Generazione audio in corso..."):
90
+ try:
91
+ # Assicurati che il modello sia già su CPU dal caricamento
92
+ audio_output = stable_audio_pipeline(
93
+ prompt=caption,
94
+ audio_end_in_s=duration_seconds
95
+ ).audios
96
+
97
+ audio_data = audio_output[0].cpu().numpy()
98
+ sample_rate = stable_audio_pipeline.sample_rate
99
+
100
+ audio_data = audio_data.astype(np.float32)
101
+ audio_data = librosa.util.normalize(audio_data)
102
+
103
+ buffer = io.BytesIO()
104
+ sf.write(buffer, audio_data, sample_rate, format='WAV')
105
+ buffer.seek(0)
106
+ return buffer.getvalue(), sample_rate
107
+
108
+ except Exception as e:
109
+ st.error(f"Errore durante la generazione dell'audio: {e}")
110
+ return None, None
111
+
112
+
113
+ # --- 3. Interfaccia Streamlit ---
114
+ st.title("Generatore di Paesaggi Sonori da Immagini")
115
+ st.write("Carica un'immagine e otterrai una descrizione testuale e un paesaggio sonoro generato!")
116
+
117
+ uploaded_file = st.file_uploader("Scegli un'immagine...", type=["jpg", "jpeg", "png"])
118
+
119
+ if uploaded_file is not None:
120
+ input_image = Image.open(uploaded_file)
121
+ st.image(input_image, caption='Immagine Caricata.', use_column_width=True)
122
+ st.write("")
123
+
124
+ audio_duration = st.slider("Durata audio (secondi):", 5, 30, 10, key="audio_duration_slider")
125
+
126
+
127
+ if st.button("Genera Paesaggio Sonoro"):
128
+ st.subheader("Processo in Corso...")
129
+
130
+ # PASSO 1: Genera la caption
131
+ st.write("Generazione della caption...")
132
+ caption = generate_image_caption(input_image)
133
+ st.write(f"Caption generata: **{caption}**")
134
+
135
+ # PASSO 2: Genera il soundscape
136
+ st.write("Generazione del paesaggio sonoro...")
137
+ audio_data_bytes, sample_rate = generate_soundscape_from_caption(caption, duration_seconds=audio_duration)
138
+
139
+ if audio_data_bytes is not None:
140
+ st.subheader("Paesaggio Sonoro Generato")
141
+ st.audio(audio_data_bytes, format='audio/wav', sample_rate=sample_rate)
142
+
143
+ st.download_button(
144
+ label="Scarica Audio WAV",
145
+ data=audio_data_bytes,
146
+ file_name="paesaggio_sonoro_generato.wav",
147
+ mime="audio/wav"
148
+ )
149
+ else:
150
+ st.error("La generazione del paesaggio sonoro è fallita.")
requirements.txt CHANGED
@@ -1,3 +1,81 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ accelerate==1.8.1
2
+ altair==5.5.0
3
+ attrs==25.3.0
4
+ audioop-lts==0.2.1
5
+ audioread==3.0.1
6
+ blinker==1.9.0
7
+ cachetools==6.1.0
8
+ certifi==2025.6.15
9
+ cffi==1.17.1
10
+ charset-normalizer==3.4.2
11
+ click==8.2.1
12
+ decorator==5.2.1
13
+ diffusers==0.33.1
14
+ filelock==3.13.1
15
+ fsspec==2024.6.1
16
+ gitdb==4.0.12
17
+ GitPython==3.1.44
18
+ hf-xet==1.1.5
19
+ huggingface-hub==0.33.0
20
+ idna==3.10
21
+ importlib_metadata==8.7.0
22
+ Jinja2==3.1.4
23
+ joblib==1.5.1
24
+ jsonschema==4.24.0
25
+ jsonschema-specifications==2025.4.1
26
+ lazy_loader==0.4
27
+ librosa==0.11.0
28
+ llvmlite==0.44.0
29
+ MarkupSafe==2.1.5
30
+ mpmath==1.3.0
31
+ msgpack==1.1.1
32
+ narwhals==1.43.1
33
+ networkx==3.3
34
+ numba==0.61.2
35
+ numpy==2.1.2
36
+ packaging==25.0
37
+ pandas==2.3.0
38
+ pillow==11.0.0
39
+ platformdirs==4.3.8
40
+ pooch==1.8.2
41
+ protobuf==6.31.1
42
+ psutil==7.0.0
43
+ pyarrow==20.0.0
44
+ pycparser==2.22
45
+ pydeck==0.9.1
46
+ python-dateutil==2.9.0.post0
47
+ pytz==2025.2
48
+ PyYAML==6.0.2
49
+ referencing==0.36.2
50
+ regex==2024.11.6
51
+ requests==2.32.4
52
+ rpds-py==0.25.1
53
+ safetensors==0.5.3
54
+ scikit-learn==1.7.0
55
+ scipy==1.15.3
56
+ setuptools==70.2.0
57
+ six==1.17.0
58
+ smmap==5.0.2
59
+ soundfile==0.13.1
60
+ soxr==0.5.0.post1
61
+ standard-aifc==3.13.0
62
+ standard-chunk==3.13.0
63
+ standard-sunau==3.13.0
64
+ streamlit==1.46.0
65
+ sympy==1.13.3
66
+ tenacity==9.1.2
67
+ threadpoolctl==3.6.0
68
+ tokenizers==0.21.1
69
+ toml==0.10.2
70
+ torch==2.7.1
71
+ torchaudio==2.7.1
72
+ torchsde==0.2.6
73
+ torchvision==0.22.1
74
+ tornado==6.5.1
75
+ tqdm==4.67.1
76
+ trampoline==0.1.2
77
+ transformers==4.52.4
78
+ typing_extensions==4.12.2
79
+ tzdata==2025.2
80
+ urllib3==2.5.0
81
+ zipp==3.23.0