Spaces:
Runtime error
Runtime error
File size: 6,688 Bytes
e8f3c21 |
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 |
import gradio as gr
from transformers import pipeline, AutoModelForSpeechSeq2Seq, AutoTokenizer, AutoProcessor
import torch
import logging
import os
import time
import shutil # เพิ่มการ import shutil
from pydub import AudioSegment, silence
from concurrent.futures import ProcessPoolExecutor
from io import StringIO
# ตั้งค่า logging
log_stream = StringIO()
logging.basicConfig(level=logging.DEBUG, stream=log_stream)
logger = logging.getLogger(__name__)
# กำหนด path สำหรับ model, audio, segment, และ text
MODEL_DIR = "/content/model"
AUDIO_DIR = "/content/audio"
TEXT_DIR = "/content/text"
# สร้าง directories ถ้ายังไม่มี
os.makedirs(MODEL_DIR, exist_ok=True)
os.makedirs(AUDIO_DIR, exist_ok=True)
os.makedirs(TEXT_DIR, exist_ok=True)
# กำหนดชื่อโมเดลและภาษา
MODEL_NAME = "FILM6912/Whisper-small-thai"
lang = "th"
# ตรวจสอบว่าใช้ GPU ได้หรือไม่ ถ้าไม่ได้ใช้ CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
logger.info(f"Using device: {'GPU' if device.type == 'cuda' else 'CPU'}")
# โหลดโมเดลและ Tokenizer ล่วงหน้าเพื่อเก็บใน cache directory
try:
logger.info("Loading model...")
model = AutoModelForSpeechSeq2Seq.from_pretrained(MODEL_NAME, cache_dir=MODEL_DIR).to(device)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, cache_dir=MODEL_DIR)
processor = AutoProcessor.from_pretrained(MODEL_NAME, cache_dir=MODEL_DIR)
# สร้าง pipeline สำหรับการแปลงเสียงเป็นข้อความ
pipe = pipeline(
task="automatic-speech-recognition",
model=model,
tokenizer=tokenizer,
feature_extractor=processor.feature_extractor,
chunk_length_s=30,
device=0 if device.type == 'cuda' else -1, # บังคับให้ใช้ GPU (device=0) ถ้ามี
)
logger.info("Model loaded successfully.")
except Exception as e:
logger.error(f"Error loading model: {e}")
raise
# ฟังก์ชันสำหรับการถอดเสียงแบบขนาน
def transcribe_segment(segment: AudioSegment):
try:
# ส่งออก segment เป็นไฟล์ WAV ในหน่วยความจำ
segment_wav = segment.export(format="wav")
# ถอดเสียงจากไฟล์ segment
transcription = pipe(segment_wav)["text"]
return transcription
except Exception as e:
logger.error(f"Error during segment transcription: {e}")
return ""
# ฟังก์ชันสำหรับการแปลงเสียงเป็นข้อความ
def transcribe_with_parallel_processing(microphone_audio, upload_audio):
audio_path = microphone_audio or upload_audio
# ตรวจสอบเส้นทางไฟล์เพื่อให้แน่ใจว่าไฟล์มีอยู่จริง
if not audio_path or not os.path.exists(audio_path):
logger.error("No audio input received or file does not exist.")
return "No audio input received or file does not exist.", None, None
logger.debug(f"Processing audio file: {audio_path}")
# 8387rcPNz8SRX6pYXgdxCZg3VMLFwtdJB3Z9LeX8Ge2n
sanitized_filename = os.path.basename(audio_path).replace(" ", "_")
audio_filename = os.path.join(AUDIO_DIR, sanitized_filename)
shutil.copyfile(audio_path, audio_filename)
try:
# โหลดไฟล์เสียงด้วย pydub
audio = AudioSegment.from_wav(audio_filename)
# แบ่งไฟล์เสียงเมื่อเสียงเงียบ
chunks = silence.split_on_silence(audio, min_silence_len=1000, silence_thresh=-30, keep_silence=500)
logger.info(f"Audio split into {len(chunks)} segments.")
if not chunks:
logger.error("No segments created. Ensure the audio file is correct.")
return "No segments created. Ensure the audio file is correct.", None, log_stream.getvalue()
# ถอดเสียงแบบขนาน
with ProcessPoolExecutor() as executor:
transcriptions = list(executor.map(transcribe_segment, chunks))
# รวมผลลัพธ์จากแต่ละส่วนเข้าด้วยกัน
full_transcription = " ".join(transcriptions)
logger.info("Transcription completed successfully.")
# บันทึกผลลัพธ์เป็นไฟล์ .txt โดยตั้งชื่อไฟล์ตาม Unix Time
output_filename = os.path.join(TEXT_DIR, f"transcription_{int(time.time())}.txt")
with open(output_filename, "w", encoding="utf-8") as file:
file.write(full_transcription)
logger.info(f"Transcription exported to {output_filename}.")
# ลบไฟล์เสียงต้นฉบับหลังการใช้งานเสร็จสิ้น
os.remove(audio_filename)
return full_transcription, output_filename, log_stream.getvalue()
except Exception as e:
logger.error(f"Error during transcription: {e}")
return "Error during transcription.", None, log_stream.getvalue()
# สร้างอินเทอร์เฟซด้วย Gradio พร้อมปุ่มยืนยัน
with gr.Blocks() as interface:
with gr.Row():
audio_input = gr.Audio(type="filepath", label="Record or Upload your voice") # ใช้ filepath สำหรับการบันทึกเสียง
submit_btn = gr.Button("Start Transcription")
output_text = gr.Textbox(label="Transcription")
output_file = gr.File(label="Download Transcription File")
log_output = gr.Textbox(label="Logs", lines=10) # ช่องสำหรับแสดง logs
submit_btn.click(
fn=transcribe_with_parallel_processing,
inputs=[audio_input, audio_input], # ใช้ input เดียวกันสำหรับไฟล์อัปโหลดและการบันทึก
outputs=[output_text, output_file, log_output] # เพิ่ม log_output สำหรับแสดง logs
)
# รันแอปพลิเคชันและแชร์ลิงก์
logger.info("Launching Gradio interface...")
interface.launch(share=True)
logger.info("Gradio interface launched successfully.")
|