deepseeksrtmm / app.py
Dubberkuro's picture
Update app.py
16b9f48 verified
import os
import subprocess
import tempfile
import gradio as gr
import torch
import shutil
from transformers import (
AutoTokenizer,
AutoModelForCausalLM,
WhisperForConditionalGeneration,
WhisperProcessor
)
import librosa
# --- မော်ဒယ်များကို စတင်တင်ဆောင်ခြင်း (Model Loading) ---
print("🔄 မော်ဒယ်များ တင်ဆောင်နေသည်...")
device = "cuda" if torch.cuda.is_available() else "cpu"
# ==============================================
# ၁။ ASR မော်ဒယ် (Hugging Face Transformers ဖြင့်)
# ==============================================
asr_model_id = "Chonlasitk/whisper-burmese"
print(f"⏳ ASR မော်ဒယ် ({asr_model_id}) ကို တင်ဆောင်နေသည်...")
# Whisper Processor က audio ကို input features အဖြစ် ပြောင်းပေးပြီး
# WhisperForConditionalGeneration က text ထုတ်ပေးပါတယ်။
processor = WhisperProcessor.from_pretrained(asr_model_id)
asr_model = WhisperForConditionalGeneration.from_pretrained(asr_model_id).to(device)
print(f"✅ ASR မော်ဒယ်ကို {device} ပေါ်တွင် တင်ဆောင်ပြီးပါပြီ။")
# ==============================================
# ၂။ ဘာသာပြန် LLM မော်ဒယ် (MIG Burmese LLM)
# ==============================================
translation_model_id = "Ko-Yin-Maung/mig-burmese-llm"
print(f"⏳ ဘာသာပြန် LLM မော်ဒယ် ({translation_model_id}) ကို တင်ဆောင်နေသည်...")
try:
translation_tokenizer = AutoTokenizer.from_pretrained(translation_model_id)
if device == "cuda":
translation_model = AutoModelForCausalLM.from_pretrained(
translation_model_id,
torch_dtype=torch.float16,
device_map="auto"
)
else:
translation_model = AutoModelForCausalLM.from_pretrained(
translation_model_id,
device_map="auto"
)
print(f"✅ ဘာသာပြန် LLM မော်ဒယ်ကို တင်ဆောင်ပြီးပါပြီ။")
except Exception as e:
print(f"❌ ဘာသာပြန်မော်ဒယ်ကို တင်ဆောင်ရာတွင် အမှားတွေ့ရှိသည်: {e}")
exit()
print("🚀 အားလုံး အဆင်သင့်ဖြစ်ပါပြီ။ Gradio App ကို စတင်လိုက်ပါ။")
# --- အကူအညီ ဖန်ရှင်များ (Helper Functions) ---
def extract_audio(video_path):
"""ဗီဒီယိုဖိုင်မှ အသံကို 16kHz Mono WAV format ဖြင့် ထုတ်ယူပါ။"""
print("🔊 ဗီဒီယိုမှ အသံထုတ်ယူနေသည်...")
audio_path = "extracted_audio.wav"
command = [
"ffmpeg",
"-i", video_path,
"-ac", "1",
"-ar", "16000",
"-vn",
"-f", "wav",
"-y",
audio_path
]
subprocess.run(command, check=True, capture_output=True)
print(f"✅ အသံထုတ်ယူပြီးပါပြီ: {audio_path}")
return audio_path
def transcribe_audio(audio_path):
"""
Hugging Face Whisper မော်ဒယ်ကို သုံး၍ အသံကို စာသားပြောင်းပါ။
အချိန်ကုဒ် segment များပါ ထုတ်ပေးပါသည်။
"""
print("🎤 အသံကို စာသားပြောင်းနေသည်...")
# Audio ဖိုင်ကို 16kHz sampling rate နဲ့ ဖတ်ပါ
audio_array, sampling_rate = librosa.load(audio_path, sr=16000)
# Whisper Processor က input features ပြင်ဆင်ပေးပါတယ်
inputs = processor(audio_array, sampling_rate=16000, return_tensors="pt").input_features
inputs = inputs.to(device)
# Model ကို generate လုပ်ပြီး token ids ရယူပါ
with torch.no_grad():
generated_ids = asr_model.generate(
inputs,
task="transcribe",
return_timestamps=True, # အချိန်ကုဒ်ပါ ထုတ်ပေးရန် အရေးကြီးပါသည်
max_new_tokens=448,
language="burmese", # မြန်မာဘာသာစကားကို တိုက်ရိုက်သတ်မှတ်
)
# Token ids မှ text နှင့် timestamps ပါတဲ့ result ကို decode လုပ်ပါ
transcription = processor.decode(generated_ids[0], skip_special_tokens=True, output_offsets=True)
# Whisper ရဲ့ decode က dictionary ပုံစံ {text: "...", offsets: [...]} ပြန်ပေးပါတယ်
# offsets ထဲမှာ တစ်ခုချင်းစီရဲ့ timestamp ပါပါတယ်။
segments = []
if "offsets" in transcription:
for offset in transcription["offsets"]:
if "text" in offset and "timestamp" in offset:
start, end = offset["timestamp"]
segments.append({
"start": start,
"end": end,
"text": offset["text"].strip()
})
# အကယ်၍ segments မရခဲ့ရင် fallback အနေနဲ့ text တစ်ခုလုံးကို ယူပါမယ်
if not segments:
full_text = transcription.get("text", "").strip()
if full_text:
segments.append({"start": 0.0, "end": len(audio_array)/16000, "text": full_text})
print(f"✅ စာသားပြောင်းပြီးပါပြီ။ Segment {len(segments)} ခုရရှိသည်။")
return segments
def translate_to_burmese(text):
"""အင်္ဂလိပ်စာသားကို MIG Burmese LLM သုံး၍ မြန်မာဘာသာသို့ ပြန်ဆိုပါ။"""
if not text or text.isspace():
return ""
# MIG Burmese LLM အတွက် prompt format
prompt = f"<start_of_turn>user\nTranslate to Myanmar: {text}\n<end_of_turn><start_of_turn>model\n"
inputs = translation_tokenizer(prompt, return_tensors="pt").to(translation_model.device)
with torch.no_grad():
outputs = translation_model.generate(
**inputs,
max_new_tokens=512,
do_sample=False,
temperature=0.7,
)
translated = translation_tokenizer.decode(outputs[0], skip_special_tokens=True)
# "model\n" နောက်မှ ရလဒ်ကို ထုတ်ယူပါ
try:
result = translated.split("model\n")[-1].strip()
return result
except:
return translated
def format_timestamp(seconds):
"""စက္ကန့်ကို SRT အချိန်ကုဒ် format (HH:MM:SS,ms) သို့ပြောင်းပါ။"""
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
millis = int((seconds - int(seconds)) * 1000)
return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
def process_video(video_file, progress=gr.Progress()):
"""
ဗီဒီယိုကို အဆင့်လိုက် လုပ်ဆောင်ပေးမယ့် အဓိက ဖန်ရှင်။
"""
if video_file is None:
raise gr.Error("ကျေးဇူးပြု၍ ဗီဒီယိုဖိုင်တစ်ခု အပ်လုဒ်လုပ်ပါ။")
progress(0, desc="စတင်နေပါပြီ...")
audio_path = None
srt_file_path = None
try:
# --- အဆင့် ၁: အသံထုတ်ယူခြင်း ---
progress(0.1, desc="ဗီဒီယိုမှ အသံထုတ်ယူနေသည်...")
audio_path = extract_audio(video_file)
# --- အဆင့် ၂: ASR ပြုလုပ်ခြင်း (Whisper) ---
progress(0.3, desc="အသံကို စာသားပြောင်းနေသည်... (ASR)")
segments = transcribe_audio(audio_path)
if not segments:
raise gr.Error("အသံဖိုင်ထဲတွင် စာသားပြောင်းရန် အကြောင်းအရာ မရှိပါ။")
# --- အဆင့် ၃: ဘာသာပြန်ခြင်း ---
progress(0.6, desc="မြန်မာဘာသာသို့ ပြန်ဆိုနေသည်...")
total_segments = len(segments)
burmese_segments = []
for i, segment in enumerate(segments):
progress(0.6 + (0.3 * (i / total_segments)),
desc=f"မြန်မာပြန်ဆိုနေသည်... ({i+1}/{total_segments})")
english_text = segment["text"].strip()
if english_text:
burmese_text = translate_to_burmese(english_text)
burmese_segments.append(burmese_text)
else:
burmese_segments.append("")
# --- အဆင့် ၄: SRT ဖိုင်ဖန်တီးခြင်း ---
progress(0.95, desc="SRT ဖိုင်ကို ဖန်တီးနေသည်...")
srt_filename = "subtitles.srt"
with open(srt_filename, "w", encoding="utf-8") as f:
for i, segment in enumerate(segments):
if i < len(burmese_segments) and burmese_segments[i]:
start_time = format_timestamp(segment["start"])
end_time = format_timestamp(segment["end"])
f.write(f"{i+1}\n")
f.write(f"{start_time} --> {end_time}\n")
f.write(f"{burmese_segments[i]}\n\n")
srt_file_path = srt_filename
progress(1.0, desc="ပြီးစီးပါပြီ။")
return "✅ လုပ်ငန်းစဉ်အောင်မြင်စွာ ပြီးစီးပါပြီ။ SRT ဖိုင်ကို အောက်ပါလင့်ခ်မှ ဒေါင်းလုဒ်ရယူနိုင်ပါသည်။", srt_file_path
except subprocess.CalledProcessError as e:
raise gr.Error(f"FFmpeg အမှား: {e.stderr.decode('utf-8')}")
except Exception as e:
raise gr.Error(f"မမျှော်လင့်ထားသော အမှားတစ်ခု ဖြစ်ပွားခဲ့သည်: {e}")
finally:
if audio_path and os.path.exists(audio_path):
os.remove(audio_path)
print(f"🧹 ယာယီအသံဖိုင် {audio_path} ကို ရှင်းလင်းပြီးပါပြီ။")
# --- Gradio Interface ဖန်တီးခြင်း ---
with gr.Blocks(theme=gr.themes.Soft(), title="မြန်မာစာတန်းထိုး ဖန်တီးရေး") as demo:
gr.Markdown("""
# 🇲🇲 မြန်မာစာတန်းထိုး အလိုအလျောက် ဖန်တီးရေး (Auto Burmese Subtitle Generator)
ဗီဒီယိုဖိုင်တစ်ခု အပ်လုဒ်လုပ်လိုက်ရုံနဲ့ အသံကို နားထောင်ပြီး မြန်မာလို အချိန်နဲ့တစ်ပြေးညီ စာတန်းထိုး (SRT) ဖိုင်ကို အလိုအလျောက် ထုတ်ပေးပါမယ်။
""")
with gr.Row():
with gr.Column(scale=1):
video_input = gr.Video(label="ဗီဒီယိုဖိုင် ထည့်ရန်", sources=["upload"])
submit_btn = gr.Button("စာတန်းထိုးဖန်တီးမည်", variant="primary")
with gr.Column(scale=1):
status_output = gr.Textbox(label="အခြေအနေ", interactive=False)
srt_output = gr.File(label="မြန်မာစာတန်းထိုး (SRT) ဖိုင်", interactive=False)
submit_btn.click(
fn=process_video,
inputs=[video_input],
outputs=[status_output, srt_output]
)
gr.Markdown("""
---
### ℹ️ အသုံးပြုနည်း
၁။ `ဗီဒီယိုဖိုင် ထည့်ရန်` အကွက်ကို နှိပ်၍ သင့်စက်ထဲမှ ဗီဒီယိုတစ်ခုကို ရွေးချယ်ပါ။
၂။ `စာတန်းထိုးဖန်တီးမည်` ခလုတ်ကို နှိပ်ပါ။
၃။ လုပ်ငန်းစဉ် ပြီးစီးသည်အထိ စောင့်ပါ။
၄။ ပြီးစီးသွားပါက `မြန်မာစာတန်းထိုး (SRT) ဖိုင်` အကွက်မှ ဒေါင်းလုဒ်ရယူနိုင်ပါပြီ။
""")
if __name__ == "__main__":
demo.launch(debug=True)