Spaces:
Sleeping
Sleeping
import streamlit as st | |
import torch | |
import librosa | |
import numpy as np | |
from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor | |
import io | |
from datetime import datetime | |
import gc | |
import warnings | |
warnings.filterwarnings('ignore') | |
# Konfiguracja strony i optymalizacja pami臋ci | |
st.set_page_config( | |
page_title="Transkrypcja Audio - Polski", | |
page_icon="馃帳", | |
layout="centered" # zmniejszone zu偶ycie miejsca | |
) | |
# Optymalizacja torch | |
torch.backends.cudnn.benchmark = True | |
if torch.cuda.is_available(): | |
torch.cuda.empty_cache() | |
# cache wygasa po godzinie | |
def zaladuj_model(): | |
"""艁aduje model i procesor z cache z obs艂ug膮 b艂臋d贸w""" | |
try: | |
nazwa_modelu = "jonatasgrosman/wav2vec2-large-xlsr-53-polish" | |
procesor = Wav2Vec2Processor.from_pretrained(nazwa_modelu) | |
model = Wav2Vec2ForCTC.from_pretrained(nazwa_modelu) | |
# Optymalizacja modelu | |
if torch.cuda.is_available(): | |
model = model.to('cuda') | |
model.eval() # tryb ewaluacji | |
return procesor, model | |
except Exception as e: | |
st.error(f"B艂膮d 艂adowania modelu: {str(e)}") | |
return None, None | |
# cache na 5 minut dla danych audio | |
def przetworz_audio(audio_bytes): | |
"""Wst臋pne przetwarzanie audio z optymalizacj膮 pami臋ci""" | |
try: | |
# U偶ywamy ma艂ych fragment贸w do przetwarzania | |
y, sr = librosa.load(io.BytesIO(audio_bytes), sr=16000, mono=True) | |
return y, sr | |
except Exception as e: | |
st.error(f"B艂膮d przetwarzania audio: {str(e)}") | |
return None, None | |
def transkrybuj_audio(audio, procesor, model, chunk_length_s=30): | |
"""Transkrybuje audio w chunks dla optymalizacji pami臋ci""" | |
try: | |
# Podziel audio na chunki | |
sample_rate = 16000 | |
chunk_length = chunk_length_s * sample_rate | |
chunks = [audio[i:i + chunk_length] for i in range(0, len(audio), chunk_length)] | |
pelna_transkrypcja = [] | |
# Przetwarzaj ka偶dy chunk osobno | |
for chunk in chunks: | |
if len(chunk) < 100: # pomijamy zbyt kr贸tkie chunki | |
continue | |
inputs = procesor(chunk, sampling_rate=sample_rate, return_tensors="pt", padding=True) | |
if torch.cuda.is_available(): | |
inputs = inputs.input_values.to('cuda') | |
else: | |
inputs = inputs.input_values | |
with torch.no_grad(): | |
logits = model(inputs).logits | |
predicted_ids = torch.argmax(logits, dim=-1) | |
transkrypcja = procesor.batch_decode(predicted_ids)[0] | |
pelna_transkrypcja.append(transkrypcja) | |
# Czyszczenie pami臋ci | |
del inputs, logits, predicted_ids | |
torch.cuda.empty_cache() if torch.cuda.is_available() else gc.collect() | |
return " ".join(pelna_transkrypcja) | |
except Exception as e: | |
st.error(f"B艂膮d transkrypcji: {str(e)}") | |
return "" | |
def main(): | |
st.title("馃帳 Transkrypcja Audio w J臋zyku Polskim") | |
# 艁adowanie modelu | |
procesor, model = zaladuj_model() | |
if procesor is None or model is None: | |
st.stop() | |
# Limit rozmiaru pliku (10MB) | |
plik_audio = st.file_uploader( | |
"Wybierz plik audio (max 30MB)", | |
type=['wav', 'mp3', 'ogg', 'm4a'], | |
accept_multiple_files=False | |
) | |
if plik_audio is not None: | |
# Sprawdzenie rozmiaru pliku | |
if plik_audio.size > 10 * 1024 * 3072: # 30MB | |
st.error("Plik jest zbyt du偶y. Maksymalny rozmiar to 30MB.") | |
st.stop() | |
st.audio(plik_audio) | |
if st.button("Rozpocznij transkrypcj臋", type="primary"): | |
progress_bar = st.progress(0) | |
status_text = st.empty() | |
try: | |
# Przetwarzanie audio | |
status_text.text("Przetwarzanie audio...") | |
progress_bar.progress(25) | |
audio, sr = przetworz_audio(plik_audio.getvalue()) | |
if audio is None: | |
st.stop() | |
# Transkrypcja | |
status_text.text("Trwa transkrypcja...") | |
progress_bar.progress(50) | |
transkrypcja = transkrybuj_audio(audio, procesor, model) | |
# Wy艣wietlenie wyniku | |
progress_bar.progress(100) | |
status_text.text("Zako艅czono!") | |
if transkrypcja: | |
st.markdown("### Wynik transkrypcji:") | |
st.text_area("", transkrypcja, height=200) | |
# Przycisk pobierania | |
nazwa_pliku = f"transkrypcja_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt" | |
st.download_button( | |
"馃摜 Pobierz transkrypcj臋", | |
transkrypcja.encode('utf-8'), | |
nazwa_pliku, | |
mime="text/plain" | |
) | |
# Czyszczenie | |
del audio | |
gc.collect() | |
except Exception as e: | |
st.error(f"Wyst膮pi艂 nieoczekiwany b艂膮d: {str(e)}") | |
finally: | |
progress_bar.empty() | |
status_text.empty() | |
# Informacje | |
with st.expander("鈩癸笍 Informacje o aplikacji"): | |
st.markdown(""" | |
- Model: Wav2Vec2-Large-XLSR-53-Polish | |
- Maksymalny rozmiar pliku: 10MB | |
- Obs艂ugiwane formaty: WAV, MP3, OGG, M4A | |
- J臋zyk: Polski | |
""") | |
if __name__ == "__main__": | |
main() | |