Update app.py
Browse files
app.py
CHANGED
|
@@ -1,60 +1,59 @@
|
|
| 1 |
-
import
|
| 2 |
-
import gradio as gr
|
| 3 |
from groq import Groq
|
| 4 |
|
| 5 |
-
#
|
| 6 |
-
GROQ_API_KEY =
|
|
|
|
| 7 |
|
| 8 |
-
def
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
try:
|
| 16 |
-
# سا
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
-
#
|
| 20 |
-
|
| 21 |
-
response = client.audio.transcriptions.create(
|
| 22 |
-
file=(audio_path, file.read()),
|
| 23 |
-
model="whisper-large-v3-turbo", # مدل ویسپر ۳ توربو
|
| 24 |
-
response_format="verbose_json", # فرمت خروجی حاوی زمانبندی
|
| 25 |
-
language="fa" # زبان فارسی
|
| 26 |
-
)
|
| 27 |
|
| 28 |
-
# دریا
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
| 41 |
|
| 42 |
-
return full_text, segments
|
| 43 |
-
|
| 44 |
except Exception as e:
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
demo = gr.Interface(
|
| 49 |
-
fn=transcribe_audio,
|
| 50 |
-
inputs=gr.Audio(type="filepath", label="فایل صوتی خود را اینجا بکشید و رها کنید"),
|
| 51 |
-
outputs=[
|
| 52 |
-
gr.Textbox(label="متن کامل شناسایی شده (Full Text)"),
|
| 53 |
-
gr.JSON(label="زمانبندی دقیق جملات (Segments)")
|
| 54 |
-
],
|
| 55 |
-
title="تست ابزار تبدیل صدا به متن Whisper v3",
|
| 56 |
-
description="فایل صوتی خود را آپلود کنید تا خروجی متنی و زمانبندی دقیق کلمات را در محیط هاگینگ فیس مشاهده کنید."
|
| 57 |
-
)
|
| 58 |
-
|
| 59 |
-
if __name__ == "__main__":
|
| 60 |
-
demo.launch()
|
|
|
|
| 1 |
+
import json
|
|
|
|
| 2 |
from groq import Groq
|
| 3 |
|
| 4 |
+
# استفاده از همان کلاینت و کلید قبلی شما
|
| 5 |
+
GROQ_API_KEY = "gsk_کلید_شما"
|
| 6 |
+
client = Groq(api_key=GROQ_API_KEY)
|
| 7 |
|
| 8 |
+
def correct_segments_with_llm(segments_list):
|
| 9 |
+
"""
|
| 10 |
+
این تابع لیست سگمنتها را میگیرد و غلطهای املایی را بدون تغییر لحن کلمات اصلاح میکند.
|
| 11 |
+
"""
|
| 12 |
+
# تبدیل لیست به متن JSON برای فرستادن به هوش مصنوعی
|
| 13 |
+
segments_json = json.dumps(segments_list, ensure_ascii=False, indent=2)
|
| 14 |
|
| 15 |
+
# دستورالعمل فوقالعاده دقیق برای جلوگیری از تغییر کلمات
|
| 16 |
+
system_instruction = (
|
| 17 |
+
"تو یک ویراستار حرفهای زیرنویس فارسی هستی. وظیفه تو فقط و فقط اصلاح غلطهای املایی و شنیداری (Phonetic Errors) در این JSON است.\n"
|
| 18 |
+
"قوانین بسیار سختگیرانه که باید رعایت کنی:\n"
|
| 19 |
+
"۱. به هیچ وجه لحن جملات را تغییر نده. کلمات عامیانه و محاورهای باید دقیقاً همانطور بمانند.\n"
|
| 20 |
+
"۲. ساختار نوشتاری کلمات را تغییر نده. به عنوان مثال، اگر کلمهای به صورت 'میباشد' نوشته شده، آن را به 'می باشد' یا 'هست' تغییر نده. اگر کلمهای درست است، هیچ تغییری در ظاهر آن (حتی فاصلهگذاریها) ایجاد نکن.\n"
|
| 21 |
+
"۳. جملات را خلاصه نکن، بازنویسی نکن و هیچ کلمهای را حذف یا اضافه نکن.\n"
|
| 22 |
+
"۴. زمانبندیها (بخش، شروع، پایان) نباید کوچکترین تغییری کنند.\n"
|
| 23 |
+
"۵. خروجی تو باید دقیقاً یک JSON معتبر با همان ساختار ورودی باشد. هیچ توضیح، سلام، احوالپرسی یا متن اضافی خارج از JSON برنگردان."
|
| 24 |
+
)
|
| 25 |
|
| 26 |
try:
|
| 27 |
+
# ارسال درخواست به مدل چت فوقسریع لاما در Groq
|
| 28 |
+
response = client.chat.completions.create(
|
| 29 |
+
model="llama-3.1-8b-instant", # مدل بسیار سریع و مناسب برای کارهای ویرایشی
|
| 30 |
+
messages=[
|
| 31 |
+
{"role": "system", "content": system_instruction},
|
| 32 |
+
{"role": "user", "content": f"لطفاً این زیرنویس را ویرایش کن:\n\n{segments_json}"}
|
| 33 |
+
],
|
| 34 |
+
temperature=0.1, # دمای پایین برای اینکه مدل خلاقیت به خرج ندهد و دقیقاً طبق دستور عمل کند
|
| 35 |
+
response_format={"type": "json_object"} # اجبار مدل به برگرداندن پاسخ در قالب JSON
|
| 36 |
+
)
|
| 37 |
|
| 38 |
+
# دریافت متن اصلاح شده و تبدیل آن به لیست پایتون
|
| 39 |
+
corrected_data = json.loads(response.choices[0].message.content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
+
# اگر خروجی به صورت یک دیکشنری با کلید خاصی برگشته باشد، آن را مدیریت میکنیم
|
| 42 |
+
if isinstance(corrected_data, dict) and "segments" in corrected_data:
|
| 43 |
+
return corrected_data["segments"]
|
| 44 |
+
elif isinstance(corrected_data, dict) and "بخشها" in corrected_data:
|
| 45 |
+
return corrected_data["بخشها"]
|
| 46 |
+
elif isinstance(corrected_data, list):
|
| 47 |
+
return corrected_data
|
| 48 |
+
else:
|
| 49 |
+
# در بیشتر مواقع مدل لیست مستقیم یا دیکشنری حاوی لیست را برمیگرداند
|
| 50 |
+
# برای اطمینان، اگر کلیدی پیدا نشد اولین لیستی که پیدا کند را برمیگرداند
|
| 51 |
+
for val in corrected_data.values():
|
| 52 |
+
if isinstance(val, list):
|
| 53 |
+
return val
|
| 54 |
+
return corrected_data
|
| 55 |
|
|
|
|
|
|
|
| 56 |
except Exception as e:
|
| 57 |
+
print(f"Error in LLM correction: {e}")
|
| 58 |
+
# در صورت بروز خطای ارتباطی، همان لیست اصلی بدون ویرایش برگشت داده میشود تا برنامه کرش نکند
|
| 59 |
+
return segments_list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|