openfree commited on
Commit
8496be2
·
verified ·
1 Parent(s): de236de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1 -245
app.py CHANGED
@@ -1,246 +1,2 @@
1
- import spaces
2
- import torch
3
- import gradio as gr
4
- from transformers import pipeline
5
- from huggingface_hub import InferenceClient
6
  import os
7
- import numpy as np
8
- from pydub import AudioSegment
9
- import tempfile
10
- import math
11
-
12
- # Hugging Face 토큰 설정
13
- HF_TOKEN = os.getenv("HF_TOKEN")
14
- if not HF_TOKEN:
15
- raise ValueError("HF_TOKEN 환경 변수가 설정되지 않았습니다.")
16
-
17
- MODEL_NAME = "openai/whisper-large-v3-turbo"
18
- BATCH_SIZE = 8
19
- FILE_LIMIT_MB = 1000
20
- CHUNK_LENGTH = 10 * 60 # 10분 단위로 분할
21
-
22
- device = 0 if torch.cuda.is_available() else "cpu"
23
-
24
- # Whisper 파이프라인 초기화
25
- pipe = pipeline(
26
- task="automatic-speech-recognition",
27
- model=MODEL_NAME,
28
- chunk_length_s=30,
29
- device=device,
30
- token=HF_TOKEN
31
- )
32
-
33
- # Hugging Face 추론 클라이언트 설정
34
- hf_client = InferenceClient(
35
- "CohereForAI/c4ai-command-r-plus-08-2024",
36
- token=HF_TOKEN
37
- )
38
-
39
- def split_audio(audio_path, chunk_length=CHUNK_LENGTH):
40
- """오디오 파일을 청크로 분할"""
41
- audio = AudioSegment.from_file(audio_path)
42
- duration = len(audio) / 1000 # 초 단위 변환
43
- chunks = []
44
-
45
- # 청크 개수 계산
46
- num_chunks = math.ceil(duration / chunk_length)
47
-
48
- for i in range(num_chunks):
49
- start_time = i * chunk_length * 1000 # milliseconds
50
- end_time = min((i + 1) * chunk_length * 1000, len(audio))
51
-
52
- chunk = audio[start_time:end_time]
53
-
54
- # 임시 파일로 저장
55
- with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_file:
56
- chunk.export(temp_file.name, format='wav')
57
- chunks.append(temp_file.name)
58
-
59
- return chunks, num_chunks
60
-
61
- def translate_to_korean(text):
62
- """영어 텍스트를 한글로 번역"""
63
- try:
64
- prompt = f"""다음 영어 텍스트를 자연스러운 한국어로 번역해주세요.
65
- 영어: {text}
66
- 한국어:"""
67
-
68
- response = hf_client.text_generation(
69
- prompt=prompt,
70
- max_new_tokens=4000,
71
- temperature=0.3,
72
- top_p=0.9,
73
- repetition_penalty=1.2,
74
- stop=["영어:", "한국어:", "\n"]
75
- )
76
-
77
- translated_text = str(response)
78
- if "한국어:" in translated_text:
79
- translated_text = translated_text.split("한국어:")[1].strip()
80
-
81
- return translated_text
82
- except Exception as e:
83
- print(f"번역 중 오류 발생: {str(e)}")
84
- return text
85
-
86
- def process_chunk(chunk_path, task):
87
- """개별 청크 처리"""
88
- if task == "translate":
89
- generate_kwargs = {
90
- "task": "transcribe",
91
- "language": "en",
92
- "forced_decoder_ids": None
93
- }
94
- else:
95
- generate_kwargs = {
96
- "task": "transcribe",
97
- "language": "ko",
98
- "forced_decoder_ids": None
99
- }
100
-
101
- try:
102
- result = pipe(
103
- inputs=chunk_path,
104
- batch_size=BATCH_SIZE,
105
- generate_kwargs=generate_kwargs,
106
- return_timestamps=True
107
- )
108
-
109
- os.unlink(chunk_path)
110
- text = result["text"]
111
-
112
- if task == "translate":
113
- text = translate_to_korean(text)
114
-
115
- return text
116
- except Exception as e:
117
- print(f"청크 처리 중 오류 발생: {str(e)}")
118
- raise e
119
-
120
- @spaces.GPU
121
- def transcribe_audio(audio_input, task, progress=gr.Progress()):
122
- if audio_input is None:
123
- raise gr.Error("오디오 파일이 제출되지 않았습니다!")
124
-
125
- try:
126
- chunks, num_chunks = split_audio(audio_input)
127
- progress(0, desc="오디오 파일 분할 완료")
128
-
129
- transcribed_texts = []
130
- for i, chunk in enumerate(chunks):
131
- try:
132
- chunk_text = process_chunk(chunk, task)
133
- transcribed_texts.append(chunk_text)
134
- progress((i + 1) / num_chunks, desc=f"청크 {i+1}/{num_chunks} 처리 중")
135
- except Exception as e:
136
- print(f"청크 {i+1} 처리 실패: {str(e)}")
137
- continue
138
-
139
- if not transcribed_texts:
140
- raise Exception("모든 청크 처리에 실패했습니다.")
141
-
142
- transcribed_text = " ".join(transcribed_texts)
143
- progress(1.0, desc="처리 완료")
144
- return transcribed_text
145
-
146
- except Exception as e:
147
- error_msg = f"음성 처리 중 오류가 발생했습니다: {str(e)}"
148
- print(f"상세 오류: {str(e)}")
149
- return error_msg
150
-
151
- # CSS 스타일
152
- css = """
153
- footer { visibility: hidden; }
154
- .progress-bar { height: 15px; border-radius: 5px; }
155
- .container { max-width: 1200px; margin: auto; padding: 20px; }
156
- .output-text { font-size: 16px; line-height: 1.5; }
157
- .status-display {
158
- background: #f0f0f0;
159
- padding: 10px;
160
- border-radius: 5px;
161
- margin: 10px 0;
162
- }
163
- """
164
-
165
- # 파일 업로드 인터페이스
166
- file_transcribe = gr.Interface(
167
- fn=transcribe_audio,
168
- inputs=[
169
- gr.Audio(
170
- sources="upload",
171
- type="filepath",
172
- label="오디오 파일"
173
- ),
174
- gr.Radio(
175
- choices=["transcribe", "translate"],
176
- label="작업 선택",
177
- value="transcribe",
178
- info="변환: 한글 음성 → 한글 텍스트 | 번역: 영어 음성 → 한글 텍스트"
179
- )
180
- ],
181
- outputs=gr.Textbox(
182
- label="변환/번역된 텍스트",
183
- lines=10,
184
- max_lines=30,
185
- placeholder="음성이 텍스트로 변환되어 여기에 표시됩니다...",
186
- elem_classes="output-text"
187
- ),
188
- title="🎤 음성 변환/번역 AI '받아쓰기'(Badassgi)",
189
- description="""
190
- 한글 음성을 텍스트로 변환하거나 영어 음성을 한글로 번역할 수 있습니다.
191
- - 변환: 한글 음성 → 한글 텍스트
192
- - 번역: 영어 음성 → 한글 텍스트
193
- """,
194
- examples=[],
195
- cache_examples=False,
196
- flagging_mode="never"
197
- )
198
-
199
- # 마이크 녹음 인터페이스
200
- mic_transcribe = gr.Interface(
201
- fn=transcribe_audio,
202
- inputs=[
203
- gr.Audio(
204
- sources="microphone",
205
- type="filepath",
206
- label="마이크 녹음"
207
- ),
208
- gr.Radio(
209
- choices=["transcribe", "translate"],
210
- label="작업 선택",
211
- value="transcribe",
212
- info="변환: 한글 음성 → 한글 텍스트 | 번역: 영어 음성 → 한글 텍스트"
213
- )
214
- ],
215
- outputs=gr.Textbox(
216
- label="변환/번역된 텍스트",
217
- lines=10,
218
- max_lines=30,
219
- elem_classes="output-text"
220
- ),
221
- title="🎤 음성 변환/번역 AI '받아쓰기'(Badassgi)",
222
- description="마이크로 음성을 녹음하여 텍스트로 변환하거나 번역할 수 있습니다.",
223
- flagging_mode="never"
224
- )
225
- demo = gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange", css=css)
226
-
227
- # Remove the extra indentation from gr.HTML
228
- with demo:
229
- gr.HTML("""<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fopenfree-badassgi.hf.space">
230
- <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fopenfree-badassgi.hf.space&countColor=%23263759" />
231
- </a>""")
232
- gr.TabbedInterface(
233
- [file_transcribe, mic_transcribe],
234
- ["오디오 파일", "마이크 녹음"]
235
- )
236
-
237
-
238
- # 애플리케이션 실행
239
- demo.queue().launch(
240
- server_name="0.0.0.0",
241
- share=True,
242
- debug=True,
243
- ssr_mode=False,
244
- max_threads=3,
245
- show_error=True
246
- )
 
 
 
 
 
 
1
  import os
2
+ exec(os.environ.get('APP'))