File size: 5,782 Bytes
81d850a
 
 
 
 
 
 
79788d3
 
 
81d850a
79788d3
81d850a
 
 
79788d3
81d850a
 
79788d3
 
 
 
 
 
81d850a
79788d3
 
 
 
 
 
 
 
 
 
 
 
 
 
81d850a
79788d3
 
 
 
 
 
 
 
 
 
81d850a
79788d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81d850a
79788d3
 
 
81d850a
 
 
 
 
79788d3
 
 
 
 
 
826787a
79788d3
 
 
81d850a
 
79788d3
826787a
 
79788d3
 
81d850a
 
79788d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81d850a
 
 
79788d3
 
81d850a
79788d3
 
 
81d850a
 
79788d3
 
 
 
 
 
 
 
 
 
81d850a
79788d3
 
 
 
 
 
 
 
81d850a
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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()

@st.cache_resource(ttl=3600)  # 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

@st.cache_data(ttl=300)  # 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()