Spaces:
Runtime error
Runtime error
File size: 9,434 Bytes
258fd02 0a1e140 8e684f6 f2f9818 3ef9463 2644f3e 3ef9463 989bff9 2b516e0 3ef9463 acfc75a d658154 acfc75a 208580f acfc75a 3162dea acfc75a 258fd02 d01af32 258fd02 0a1e140 acfc75a 48275bf d658154 48275bf acfc75a 48275bf 258fd02 acfc75a 258fd02 989bff9 acfc75a 989bff9 acfc75a 989bff9 acfc75a 45a12c7 ef01ecd acfc75a af26727 ef01ecd 0a1e140 acfc75a d658154 3c8f8cf acfc75a f7c5fc0 acfc75a 3c8f8cf af26727 acfc75a 3c8f8cf acfc75a 3c8f8cf f7c5fc0 acfc75a af26727 3c8f8cf acfc75a af26727 acfc75a 3c8f8cf 258fd02 d658154 e7ab0ec 8e684f6 acfc75a 8e684f6 258fd02 acfc75a 8e684f6 258fd02 3c8f8cf d658154 8e684f6 d658154 8e684f6 258fd02 acfc75a 258fd02 989bff9 258fd02 d658154 acfc75a 258fd02 d658154 258fd02 acfc75a 258fd02 48275bf acfc75a 48275bf acfc75a 48275bf d658154 acfc75a 48275bf d658154 258fd02 eb8bfb7 acfc75a eb8bfb7 d658154 acfc75a 3779445 acfc75a 258fd02 989bff9 3c8f8cf 258fd02 c8c0ef5 3779445 258fd02 acfc75a 258fd02 3ef9463 acfc75a | 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | import gradio as gr
import json
from datetime import datetime
import yaml
import time
import re
import os
import os.path as op
import torch
import soundfile as sf
import numpy as np
import tempfile
from download import download_model
# 🎯 خطوة السيادة الأولى: توجيه المحرك لتحميل أوزانكِ الخاصة بدلاً من المستودع العام
APP_DIR = op.dirname(op.abspath(__file__))
MODEL_ID = "Novix/SongGenerationtwo" # مستودع أوزانكِ السيادية
print(f"⏳ [Novix Core] جاري سحب الأوزان السيادية من المستودع: {MODEL_ID}...")
try:
# تحميل الأوزان مباشرة إلى البيئة المحلية للـ Space
download_model(APP_DIR, repo_id=MODEL_ID, revision="main")
print("✅ تم تحميل الأوزان السيادية لـ Novix بنجاح.")
except Exception as e:
print(f"⚠️ تنبيه أثناء تحميل الأوزان: {e}. سيتم الاعتماد على الأوزان المحلية إن وجدت.")
# تهيئة وإقلاع المحرك من الفئة الأصلية المستقرة
from levo_inference import LeVoInference
MODEL = None
EXAMPLE_LYRICS = """
[intro-medium]
[verse]
随风去流浪
我不想停留原地
原地只有无尽循环
不再规划人生
不再遵循地图
[chorus]
让我随风去流浪
邂逅未知的自己
生命最绚烂的章节
""".strip()
# قراءة قاموس التوكنز الصوتي الأصلي للموديل
vocab_path = op.join(APP_DIR, 'conf/vocab.yaml')
if op.exists(vocab_path):
with open(vocab_path, 'r', encoding='utf-8') as file:
STRUCTS = yaml.safe_load(file)
else:
STRUCTS = ['[intro]', '[intro-short]', '[intro-medium]', '[verse]', '[chorus]', '[bridge]', '[inst]', '[inst-short]', '[inst-medium]', '[outro]', '[outro-short]', '[outro-medium]']
def save_as_flac(sample_rate, audio_data):
if isinstance(audio_data, tuple):
sample_rate, audio_data = audio_data
if audio_data.dtype == np.float64:
audio_data = audio_data.astype(np.float32)
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".flac")
sf.write(temp_file, audio_data, sample_rate, format='FLAC')
return temp_file.name
# دالة التوليد الأصلية بعد ربطها بـ Novix Core
def generate_song(lyric, description=None, prompt_audio=None, genre=None, cfg_coef=None, temperature=0.1, top_k=-1, gen_type="mixed", progress=gr.Progress(track_tqdm=True)):
global MODEL
global STRUCTS
if MODEL is None:
return None, json.dumps({"error": "المحرك لم يتم تحميله في الذاكرة بعد. يرجى إعادة تحديث الصفحة أو مراجعة السجلات."})
params = {'cfg_coef': cfg_coef, 'temperature': temperature, 'top_k': top_k}
params = {k: v for k, v in params.items() if v is not None}
vocal_structs = ['[verse]', '[chorus]', '[bridge]']
sample_rate = MODEL.cfg.sample_rate
# تنسيق وتطهير الكلمات والمقاطع الهيكلية
lyric = lyric.replace("[intro]", "[intro-short]").replace("[inst]", "[inst-short]").replace("[outro]", "[outro-short]")
paragraphs = [p.strip() for p in lyric.strip().split('\n\n') if p.strip()]
if len(paragraphs) < 1:
return None, json.dumps("Lyrics can not be left blank")
paragraphs_norm = []
vocal_flag = False
for para in paragraphs:
lines = para.splitlines()
struct_tag = lines[0].strip().lower()
if struct_tag not in STRUCTS:
return None, json.dumps(f"Segments should start with a structure tag in {STRUCTS}")
if struct_tag in vocal_structs:
vocal_flag = True
if len(lines) < 2 or not [line.strip() for line in lines[1:] if line.strip()]:
return None, json.dumps("The following segments require lyrics: [verse], [chorus], [bridge]")
else:
new_para_list = []
for line in lines[1:]:
new_para_list.append(re.sub(r"[^\w\s\[\]\-\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af\u00c0-\u017f]", "", line))
new_para_str = f"{struct_tag} {'.'.join(new_para_list)}"
else:
if len(lines) > 1:
return None, json.dumps("The following segments should not contain lyrics: [intro], [intro-short], [intro-medium], [inst], [inst-short], [inst-medium], [outro], [outro-short], [outro-medium]")
else:
new_para_str = struct_tag
paragraphs_norm.append(new_para_str)
if not vocal_flag:
return None, json.dumps(f"The lyric must contain at least one of the following structures: {vocal_structs}")
lyric_norm = " ; ".join(paragraphs_norm)
if prompt_audio is not None:
genre = None
description = None
elif description is not None and description != "":
genre = None
if description[-1] != ".":
description = description + "."
progress(0.0, "⚡ [Novix Core] التوليد مستمر الآن...")
start = time.time()
# تشغيل المصفوفات الحقيقية للأوزان المستقلة
prompt_path = op.join(APP_DIR, "tools/new_prompt.pt")
audio_data = MODEL(lyric_norm, description, prompt_audio, genre, prompt_path, gen_type, params).cpu().permute(1, 0).float().numpy()
end = time.time()
input_config = {
"lyric": lyric_norm,
"genre": genre,
"prompt_audio": prompt_audio,
"description": description,
"params": params,
"inference_duration": end - start,
"timestamp": datetime.now().isoformat(),
"engine": "Novix Sovereign Studio (Independent Mode)"
}
filepath = save_as_flac(sample_rate, audio_data)
return filepath, json.dumps(input_config, indent=2)
# بناء الواجهة الاحترافية الكبرى لـ Gradio
with gr.Blocks(title="Novix Sovereign Studio Pro") as demo:
gr.Markdown("# 🎵 استوديو Novix المستقل والمملوك لك بالكامل 100%")
gr.Markdown("🛡️ تم فك الارتباط من خوادم الشركات وتوجيه النواة لأوزانكِ الخاصة للإنتاج والربح الحر.")
with gr.Row():
with gr.Column():
lyric = gr.Textbox(
label="Lyrics",
lines=5,
max_lines=15,
value=EXAMPLE_LYRICS,
info="قوالب المقاطع الصوتية المدعومة: [intro], [verse], [chorus], [bridge], [inst], [outro]"
)
with gr.Tabs(elem_id="extra-tabs"):
with gr.Tab("Genre Select"):
genre = gr.Radio(
choices=["Auto", "Pop", "Latin", "Rock", "Electronic", "Metal", "Country", "R&B/Soul", "Ballad", "Jazz", "World", "Hip-Hop", "Funk", "Soundtrack"],
label="Genre Select (Optional)",
value="Auto",
interactive=True
)
with gr.Tab("Text Prompt"):
description = gr.Textbox(
label="Song Description (Optional)",
info="اكتبي مواصفات الصوت بالأرقام أو الإنجليزية (مثال: female, sad pop, piano).",
placeholder="female, rock, motivational, electric guitar, bass guitar, drum kit.",
lines=1,
max_lines=2
)
with gr.Tab("Audio Prompt"):
prompt_audio = gr.Audio(
label="Prompt Audio (Optional)",
type="filepath"
)
with gr.Accordion("Advanced Config", open=False):
cfg_coef = gr.Slider(label="CFG Coefficient", minimum=0.1, maximum=3.0, step=0.1, value=1.8, interactive=True)
temperature = gr.Slider(label="Temperature", minimum=0.1, maximum=2.0, step=0.1, value=0.8, interactive=True)
with gr.Row():
generate_btn = gr.Button("Generate Song (Sovereign Mode)", variant="primary")
with gr.Column():
output_audio = gr.Audio(label="Generated Song", type="filepath")
output_json = gr.JSON(label="Generated Info")
generate_btn.click(
fn=generate_song,
inputs=[lyric, description, prompt_audio, genre, cfg_coef, temperature, gr.State(5000)],
outputs=[output_audio, output_json]
)
# تشغيل الإقلاع المستقل للنواة
if __name__ == "__main__":
torch.set_num_threads(1)
ckpt_path = op.join(APP_DIR, "ckpt")
# التأكد من وجود مجلد الأوزان وإقلاع النموذج فوراً
if not op.exists(ckpt_path):
os.makedirs(ckpt_path, exist_ok=True)
print("🧠 جاري صهر وبناء بيئة الاستدلال الصوتي المستقل...")
MODEL = LeVoInference(ckpt_path)
print("✅ النصر الكلي! الاستوديو شغال أوفلاين وجاهز لاستقبال ضربة زر التوليد.")
demo.launch(server_name="0.0.0.0", server_port=7860) |