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() | |