ginipick commited on
Commit
49d5a1b
ยท
verified ยท
1 Parent(s): 3414e90

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -645
app.py CHANGED
@@ -1,645 +1,2 @@
1
- import gradio as gr
2
- import subprocess
3
- import os
4
- import shutil
5
- import tempfile
6
- import torch
7
- import logging
8
- import numpy as np
9
- import re
10
- from concurrent.futures import ThreadPoolExecutor
11
- from functools import lru_cache
12
-
13
- # ๋กœ๊น… ์„ค์ •
14
- logging.basicConfig(
15
- level=logging.INFO,
16
- format='%(asctime)s - %(levelname)s - %(message)s',
17
- handlers=[
18
- logging.FileHandler('yue_generation.log'),
19
- logging.StreamHandler()
20
- ]
21
- )
22
-
23
-
24
-
25
- ################################
26
- # ๊ธฐ์กด์— ์ •์˜๋œ ํ•จ์ˆ˜ ๋ฐ ๋กœ์ง๋“ค #
27
- ################################
28
-
29
- def optimize_gpu_settings():
30
- if torch.cuda.is_available():
31
- torch.backends.cuda.matmul.allow_tf32 = True
32
- torch.backends.cudnn.benchmark = True
33
- torch.backends.cudnn.enabled = True
34
- torch.backends.cudnn.deterministic = False
35
- torch.cuda.empty_cache()
36
- torch.cuda.set_device(0)
37
- torch.cuda.Stream(0)
38
- os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:512'
39
-
40
- logging.info(f"Using GPU: {torch.cuda.get_device_name(0)}")
41
- logging.info(f"Available GPU memory: {torch.cuda.get_device_properties(0).total_memory / 1024**3:.2f} GB")
42
-
43
- if 'L40S' in torch.cuda.get_device_name(0):
44
- torch.cuda.set_per_process_memory_fraction(0.95)
45
-
46
- import logging
47
-
48
- def analyze_lyrics(lyrics, repeat_chorus=2):
49
- # ๋จผ์ € ๋ผ์ธ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , ๊ณต๋ฐฑ ์ค„ ์ œ๊ฑฐ
50
- lines = [line.strip() for line in lyrics.split('\n')]
51
- lines = [line for line in lines if line]
52
-
53
- # ๋งŒ์•ฝ ์ „์ฒด๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด ๊ฐ•์ œ๋กœ '.' ํ•œ ์ค„ ์ถ”๊ฐ€
54
- if not lines:
55
- lines = ['.']
56
- else:
57
- # ๋งˆ์ง€๋ง‰ ์ค„์ด [verse], [chorus], [bridge] ํƒœ๊ทธ๋กœ๋งŒ ๋๋‚˜๋ฉด
58
- # ์ž„์˜๋กœ '.' ํ•œ ์ค„์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์‹ค์ œ ๊ฐ€์‚ฌ ๋ผ์ธ์ด ๋˜๋„๋ก ์ฒ˜๋ฆฌ
59
- last_line_lower = lines[-1].lower()
60
- if last_line_lower in ['[verse]', '[chorus]', '[bridge]']:
61
- lines.append('.')
62
-
63
- # ๊ธฐ๋ณธ ์„น์…˜ ์ •๋ณด
64
- sections = {
65
- 'verse': 0,
66
- 'chorus': 0,
67
- 'bridge': 0,
68
- 'total_lines': len(lines)
69
- }
70
-
71
- # ์„น์…˜ ๋ผ์ธ๋“ค์„ ๋‹ด์„ ๋”•์…”๋„ˆ๋ฆฌ
72
- section_lines = {
73
- 'verse': [],
74
- 'chorus': [],
75
- 'bridge': []
76
- }
77
-
78
- current_section = None
79
- last_section_start = 0
80
-
81
- # [verse], [chorus], [bridge] ํƒœ๊ทธ๊ฐ€ ๋‚˜์˜ค๋ฉด ์„น์…˜์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ผ์ธ์„ ์ €์žฅ
82
- for i, line in enumerate(lines):
83
- lower_line = line.lower()
84
-
85
- if '[verse]' in lower_line:
86
- if current_section is not None:
87
- section_lines[current_section].extend(lines[last_section_start:i])
88
- current_section = 'verse'
89
- sections['verse'] += 1
90
- last_section_start = i + 1
91
-
92
- elif '[chorus]' in lower_line:
93
- if current_section is not None:
94
- section_lines[current_section].extend(lines[last_section_start:i])
95
- current_section = 'chorus'
96
- sections['chorus'] += 1
97
- last_section_start = i + 1
98
-
99
- elif '[bridge]' in lower_line:
100
- if current_section is not None:
101
- section_lines[current_section].extend(lines[last_section_start:i])
102
- current_section = 'bridge'
103
- sections['bridge'] += 1
104
- last_section_start = i + 1
105
-
106
- # ๋งˆ์ง€๋ง‰ ์„น์…˜์— ๋‚จ์•„ ์žˆ๋Š” ๋ผ์ธ๋“ค์„ ์ถ”๊ฐ€
107
- if current_section is not None and last_section_start < len(lines):
108
- section_lines[current_section].extend(lines[last_section_start:])
109
-
110
- # ์ฝ”๋Ÿฌ์Šค ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ
111
- if sections['chorus'] > 0 and repeat_chorus > 1:
112
- original_chorus = list(section_lines['chorus'])
113
- for _ in range(repeat_chorus - 1):
114
- section_lines['chorus'].extend(original_chorus)
115
-
116
- # ์„น์…˜๋ณ„ ๋ผ์ธ์ˆ˜ ๋กœ๊น…
117
- logging.info(
118
- f"Section line counts - Verse: {len(section_lines['verse'])}, "
119
- f"Chorus: {len(section_lines['chorus'])}, "
120
- f"Bridge: {len(section_lines['bridge'])}"
121
- )
122
-
123
- # ๋ฐ˜ํ™˜: ์„น์…˜ ์ •๋ณด, ์ „์ฒด ์„น์…˜ ์ˆ˜, ์ „์ฒด ๋ผ์ธ ์ˆ˜, ๊ฐ ์„น์…˜๋ณ„ ๋ผ์ธ ๋”•์…”๋„ˆ๋ฆฌ
124
- return sections, (sections['verse'] + sections['chorus'] + sections['bridge']), len(lines), section_lines
125
-
126
-
127
-
128
- def calculate_generation_params(lyrics):
129
- sections, total_sections, total_lines, section_lines = analyze_lyrics(lyrics)
130
-
131
- time_per_line = {
132
- 'verse': 4,
133
- 'chorus': 6,
134
- 'bridge': 5
135
- }
136
-
137
- section_durations = {}
138
- for section_type in ['verse', 'chorus', 'bridge']:
139
- lines_count = len(section_lines[section_type])
140
- section_durations[section_type] = lines_count * time_per_line[section_type]
141
-
142
- total_duration = sum(duration for duration in section_durations.values())
143
- total_duration = max(60, int(total_duration * 1.2))
144
-
145
- base_tokens = 3000
146
- tokens_per_line = 200
147
- extra_tokens = 1000
148
- total_tokens = base_tokens + (total_lines * tokens_per_line) + extra_tokens
149
-
150
- if sections['chorus'] > 0:
151
- num_segments = 4
152
- else:
153
- num_segments = 3
154
-
155
- max_tokens = min(12000, total_tokens)
156
-
157
- return {
158
- 'max_tokens': max_tokens,
159
- 'num_segments': num_segments,
160
- 'sections': sections,
161
- 'section_lines': section_lines,
162
- 'estimated_duration': total_duration,
163
- 'section_durations': section_durations,
164
- 'has_chorus': sections['chorus'] > 0
165
- }
166
-
167
- def create_temp_file(content, prefix, suffix=".txt"):
168
- temp_file = tempfile.NamedTemporaryFile(delete=False, mode="w", prefix=prefix, suffix=suffix)
169
- content = content.strip() + "\n\n"
170
- content = content.replace("\r\n", "\n").replace("\r", "\n")
171
- temp_file.write(content)
172
- temp_file.close()
173
- logging.debug(f"Temporary file created: {temp_file.name}")
174
- return temp_file.name
175
-
176
- def empty_output_folder(output_dir):
177
- try:
178
- shutil.rmtree(output_dir)
179
- os.makedirs(output_dir)
180
- logging.info(f"Output folder cleaned: {output_dir}")
181
- except Exception as e:
182
- logging.error(f"Error cleaning output folder: {e}")
183
- raise
184
-
185
- def get_last_mp3_file(output_dir):
186
- mp3_files = [f for f in os.listdir(output_dir) if f.endswith('.mp3')]
187
- if not mp3_files:
188
- logging.warning("No MP3 files found")
189
- return None
190
-
191
- mp3_files_with_path = [os.path.join(output_dir, f) for f in mp3_files]
192
- mp3_files_with_path.sort(key=os.path.getmtime, reverse=True)
193
- return mp3_files_with_path[0]
194
-
195
- def get_audio_duration(file_path):
196
- try:
197
- import librosa
198
- duration = librosa.get_duration(path=file_path)
199
- return duration
200
- except Exception as e:
201
- logging.error(f"Failed to get audio duration: {e}")
202
- return None
203
-
204
-
205
- def detect_and_select_model(text):
206
- if re.search(r'[\u3131-\u318E\uAC00-\uD7A3]', text):
207
- return "m-a-p/YuE-s1-7B-anneal-jp-kr-cot"
208
- elif re.search(r'[\u4e00-\u9fff]', text):
209
- return "m-a-p/YuE-s1-7B-anneal-zh-cot"
210
- elif re.search(r'[\u3040-\u309F\u30A0-\u30FF]', text):
211
- return "m-a-p/YuE-s1-7B-anneal-jp-kr-cot"
212
- else:
213
- return "m-a-p/YuE-s1-7B-anneal-en-cot"
214
-
215
- def install_flash_attn():
216
- try:
217
- if not torch.cuda.is_available():
218
- logging.warning("GPU not available, skipping flash-attn installation")
219
- return False
220
-
221
- cuda_version = torch.version.cuda
222
- if cuda_version is None:
223
- logging.warning("CUDA not available, skipping flash-attn installation")
224
- return False
225
-
226
- logging.info(f"Detected CUDA version: {cuda_version}")
227
-
228
- try:
229
- import flash_attn
230
- logging.info("flash-attn already installed")
231
- return True
232
- except ImportError:
233
- logging.info("Installing flash-attn...")
234
-
235
- subprocess.run(
236
- ["pip", "install", "flash-attn", "--no-build-isolation"],
237
- check=True,
238
- capture_output=True
239
- )
240
- logging.info("flash-attn installed successfully!")
241
- return True
242
-
243
- except Exception as e:
244
- logging.warning(f"Failed to install flash-attn: {e}")
245
- return False
246
-
247
- def initialize_system():
248
- optimize_gpu_settings()
249
-
250
- with ThreadPoolExecutor(max_workers=4) as executor:
251
- futures = []
252
- futures.append(executor.submit(install_flash_attn))
253
-
254
- from huggingface_hub import snapshot_download
255
-
256
- folder_path = './inference/xcodec_mini_infer'
257
- os.makedirs(folder_path, exist_ok=True)
258
- logging.info(f"Created folder at: {folder_path}")
259
-
260
- futures.append(executor.submit(
261
- snapshot_download,
262
- repo_id="m-a-p/xcodec_mini_infer",
263
- local_dir="./inference/xcodec_mini_infer",
264
- resume_download=True
265
- ))
266
-
267
- for future in futures:
268
- future.result()
269
-
270
- try:
271
- os.chdir("./inference")
272
- logging.info(f"Working directory changed to: {os.getcwd()}")
273
- except FileNotFoundError as e:
274
- logging.error(f"Directory error: {e}")
275
- raise
276
-
277
- @lru_cache(maxsize=100)
278
- def get_cached_file_path(content_hash, prefix):
279
- return create_temp_file(content_hash, prefix)
280
-
281
-
282
-
283
- def optimize_model_selection(lyrics, genre):
284
- model_path = detect_and_select_model(lyrics)
285
- params = calculate_generation_params(lyrics)
286
-
287
- has_chorus = params['sections']['chorus'] > 0
288
-
289
- model_config = {
290
- "m-a-p/YuE-s1-7B-anneal-en-cot": {
291
- "max_tokens": params['max_tokens'],
292
- "temperature": 0.8,
293
- "batch_size": 16,
294
- "num_segments": params['num_segments'],
295
- "estimated_duration": params['estimated_duration']
296
- },
297
- "m-a-p/YuE-s1-7B-anneal-jp-kr-cot": {
298
- "max_tokens": params['max_tokens'],
299
- "temperature": 0.7,
300
- "batch_size": 16,
301
- "num_segments": params['num_segments'],
302
- "estimated_duration": params['estimated_duration']
303
- },
304
- "m-a-p/YuE-s1-7B-anneal-zh-cot": {
305
- "max_tokens": params['max_tokens'],
306
- "temperature": 0.7,
307
- "batch_size": 16,
308
- "num_segments": params['num_segments'],
309
- "estimated_duration": params['estimated_duration']
310
- }
311
- }
312
-
313
- if has_chorus:
314
- for config in model_config.values():
315
- config['max_tokens'] = int(config['max_tokens'] * 1.5)
316
-
317
- return model_path, model_config[model_path], params
318
-
319
- def infer(genre_txt_content, lyrics_txt_content, num_segments, max_new_tokens):
320
- genre_txt_path = None
321
- lyrics_txt_path = None
322
-
323
- try:
324
- # ---- (1) ํ™”๋ฉด์—๋Š” ๋ณด์ด์ง€ ์•Š์ง€๋งŒ, ๋งˆ์ง€๋ง‰์— [chorus] bye ์‚ฝ์ž… ----
325
- forced_line = "[chorus] bye"
326
- tmp_lyrics = lyrics_txt_content.strip()
327
- # ์ด๋ฏธ 'bye'๊ฐ€ ๋“ค์–ด์žˆ๋Š”์ง€ ํ™•์ธ (์›ํ•œ๋‹ค๋ฉด ์กฐ๊ฑด ์ถ”๊ฐ€/์‚ญ์ œ ๊ฐ€๋Šฅ)
328
- if forced_line.lower() not in tmp_lyrics.lower():
329
- tmp_lyrics += "\n" + forced_line
330
-
331
- # ---- (2) ๊ฐ•์ œ ์‚ฝ์ž…๋œ tmp_lyrics๋ฅผ ํ†ตํ•ด ๋ชจ๋ธ ์ตœ์ ํ™”/์„ค์ • ----
332
- model_path, config, params = optimize_model_selection(tmp_lyrics, genre_txt_content)
333
- logging.info(f"Selected model: {model_path}")
334
- logging.info(f"Lyrics analysis: {params}")
335
-
336
- has_chorus = params['sections']['chorus'] > 0
337
- estimated_duration = params.get('estimated_duration', 90)
338
-
339
- # ์„ธ๊ทธ๋จผํŠธ ๋ฐ ํ† ํฐ ์ˆ˜ ์„ค์ •
340
- if has_chorus:
341
- actual_max_tokens = min(12000, int(config['max_tokens'] * 1.3)) # 30% ๋” ๋งŽ์€ ํ† ํฐ
342
- actual_num_segments = min(5, params['num_segments'] + 2) # ์ถ”๊ฐ€ ์„ธ๊ทธ๋จผํŠธ
343
- else:
344
- actual_max_tokens = min(10000, int(config['max_tokens'] * 1.2))
345
- actual_num_segments = min(4, params['num_segments'] + 1)
346
-
347
- logging.info(f"Estimated duration: {estimated_duration} seconds")
348
- logging.info(f"Has chorus sections: {has_chorus}")
349
- logging.info(f"Using segments: {actual_num_segments}, tokens: {actual_max_tokens}")
350
-
351
- genre_txt_path = create_temp_file(genre_txt_content, prefix="genre_")
352
- # tmp_lyrics(๊ฐ•์ œ ์ถ”๊ฐ€๋œ ๋ฌธ์ž์—ด)์„ ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
353
- lyrics_txt_path = create_temp_file(tmp_lyrics, prefix="lyrics_")
354
-
355
- output_dir = "./output"
356
- os.makedirs(output_dir, exist_ok=True)
357
- empty_output_folder(output_dir)
358
-
359
- command = [
360
- "python", "infer.py",
361
- "--stage1_model", model_path,
362
- "--stage2_model", "m-a-p/YuE-s2-1B-general",
363
- "--genre_txt", genre_txt_path,
364
- "--lyrics_txt", lyrics_txt_path,
365
- "--run_n_segments", str(actual_num_segments),
366
- "--stage2_batch_size", "16",
367
- "--output_dir", output_dir,
368
- "--cuda_idx", "0",
369
- "--max_new_tokens", str(actual_max_tokens),
370
- "--disable_offload_model"
371
- ]
372
-
373
- env = os.environ.copy()
374
- if torch.cuda.is_available():
375
- env.update({
376
- "CUDA_VISIBLE_DEVICES": "0",
377
- "CUDA_HOME": "/usr/local/cuda",
378
- "PATH": f"/usr/local/cuda/bin:{env.get('PATH', '')}",
379
- "LD_LIBRARY_PATH": f"/usr/local/cuda/lib64:{env.get('LD_LIBRARY_PATH', '')}",
380
- "PYTORCH_CUDA_ALLOC_CONF": "max_split_size_mb:512",
381
- "CUDA_LAUNCH_BLOCKING": "0"
382
- })
383
-
384
- # transformers ์บ์‹œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ฒ˜๋ฆฌ (๋ฒ„์ „์— ๋”ฐ๋ผ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ)
385
- try:
386
- from transformers.utils import move_cache
387
- move_cache()
388
- except Exception as e:
389
- logging.warning(f"Cache migration warning (non-critical): {e}")
390
-
391
- process = subprocess.run(
392
- command,
393
- env=env,
394
- check=False,
395
- capture_output=True,
396
- text=True
397
- )
398
-
399
- logging.info(f"Command output: {process.stdout}")
400
- if process.stderr:
401
- logging.error(f"Command error: {process.stderr}")
402
-
403
- if process.returncode != 0:
404
- logging.error(f"Command failed with return code: {process.returncode}")
405
- logging.error(f"Command: {' '.join(command)}")
406
- raise RuntimeError(f"Inference failed: {process.stderr}")
407
-
408
- last_mp3 = get_last_mp3_file(output_dir)
409
- if last_mp3:
410
- try:
411
- duration = get_audio_duration(last_mp3)
412
- logging.info(f"Generated audio file: {last_mp3}")
413
- if duration:
414
- logging.info(f"Audio duration: {duration:.2f} seconds")
415
- logging.info(f"Expected duration: {estimated_duration} seconds")
416
-
417
- if duration < estimated_duration * 0.8:
418
- logging.warning(
419
- f"Generated audio is shorter than expected: {duration:.2f}s < {estimated_duration:.2f}s"
420
- )
421
- except Exception as e:
422
- logging.warning(f"Failed to get audio duration: {e}")
423
- return last_mp3
424
- else:
425
- logging.warning("No output audio file generated")
426
- return None
427
-
428
- except Exception as e:
429
- logging.error(f"Inference error: {e}")
430
- raise
431
- finally:
432
- for path in [genre_txt_path, lyrics_txt_path]:
433
- if path and os.path.exists(path):
434
- try:
435
- os.remove(path)
436
- logging.debug(f"Removed temporary file: {path}")
437
- except Exception as e:
438
- logging.warning(f"Failed to remove temporary file {path}: {e}")
439
-
440
- #####################################
441
- # ์•„๋ž˜๋ถ€ํ„ฐ Gradio UI ๋ฐ main() ๋ถ€๋ถ„ #
442
- #####################################
443
-
444
- def update_info(lyrics):
445
- """๊ฐ€์‚ฌ ๋ณ€๊ฒฝ ์‹œ ์ถ”์ • ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜."""
446
- if not lyrics:
447
- return "No lyrics entered", "No sections detected"
448
- params = calculate_generation_params(lyrics)
449
- duration = params['estimated_duration']
450
- sections = params['sections']
451
- return (
452
- f"Estimated duration: {duration:.1f} seconds",
453
- f"Verses: {sections['verse']}, Chorus: {sections['chorus']} (Expected full length including chorus)"
454
- )
455
-
456
- def main():
457
- # ์‹œ์Šคํ…œ ์ดˆ๊ธฐํ™”
458
- initialize_system()
459
-
460
- # samples ๋””๋ ‰ํ† ๋ฆฌ ๋ฐ ์˜ˆ์ œ ํŒŒ์ผ ์ฒ˜๋ฆฌ
461
- current_dir = os.path.dirname(os.path.abspath(__file__))
462
- samples_dir = os.path.join(current_dir, 'samples')
463
- sample_audio_path = os.path.join(samples_dir, 'metal.mp3')
464
-
465
- os.makedirs(samples_dir, exist_ok=True)
466
-
467
- with gr.Blocks(css="""
468
- /* ์ „์ฒด ๋ฐฐ๊ฒฝ ๋ฐ ์ปจํ…Œ์ด๋„ˆ ์Šคํƒ€์ผ */
469
- body {
470
- background-color: #f5f5f5;
471
- }
472
- .gradio-container {
473
- max-width: 1000px;
474
- margin: auto !important;
475
- background-color: #ffffff;
476
- border-radius: 8px;
477
- padding: 20px;
478
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
479
- }
480
- h1, h2, h3 {
481
- margin: 0;
482
- padding: 0;
483
- }
484
- p {
485
- margin: 5px 0;
486
- }
487
- /* ์˜ˆ์ œ ๋ธ”๋ก ์Šคํƒ€์ผ */
488
- .gr-examples {
489
- background-color: #fafafa;
490
- border-radius: 8px;
491
- padding: 10px;
492
- }
493
- """) as demo:
494
-
495
- # ์ƒ๋‹จ ํ—ค๋”
496
- gr.HTML("""
497
- <div style="text-align: center; margin-bottom: 1.5rem;">
498
- <h1>Open SUNO: Full-Song Generation (Multi-Language Support)</h1>
499
- <p style="font-size: 1.1rem; color: #555;">
500
- Enter your song details below and let the AI handle the music production!
501
- </p>
502
- </div>
503
- """)
504
-
505
- # ์˜ˆ์ œ ์Œ์•… ์„น์…˜
506
- with gr.Group():
507
- gr.HTML("""
508
- <div style="padding: 1rem; margin-bottom: 1.5rem; background-color: #f8f9fa; border-radius: 8px; text-align: center;">
509
- <h3 style="margin: 0;">Sample Generated Music</h3>
510
- <p style="color: #666; margin: 5px 0;">Listen to this example</p>
511
- </div>
512
- """)
513
- if os.path.exists(sample_audio_path):
514
- gr.Audio(
515
- value=sample_audio_path,
516
- label="Sample Music",
517
- type="filepath"
518
- )
519
- else:
520
- gr.Markdown("### Sample music file not available")
521
-
522
- with gr.Row():
523
- # ์™ผ์ชฝ ์ž…๋ ฅ ์ปฌ๋Ÿผ
524
- with gr.Column():
525
- genre_txt = gr.Textbox(
526
- label="Genre",
527
- placeholder="Enter music genre and style descriptions...",
528
- lines=2
529
- )
530
- lyrics_txt = gr.Textbox(
531
- label="Lyrics (Supports English, Korean, Japanese, Chinese)",
532
- placeholder="Enter song lyrics with [verse], [chorus], [bridge] tags...",
533
- lines=10
534
- )
535
-
536
- # ์˜ค๋ฅธ์ชฝ ์„ค์ •/์ •๋ณด ์ปฌ๋Ÿผ
537
- with gr.Column():
538
- with gr.Group():
539
- gr.Markdown("### Generation Settings")
540
- num_segments = gr.Number(
541
- label="Number of Song Segments (Auto-adjusted)",
542
- value=2,
543
- minimum=1,
544
- maximum=4,
545
- step=1,
546
- interactive=False
547
- )
548
- max_new_tokens = gr.Slider(
549
- label="Max New Tokens (Auto-adjusted)",
550
- minimum=500,
551
- maximum=32000,
552
- step=500,
553
- value=4000,
554
- interactive=False
555
- )
556
-
557
- with gr.Group():
558
- gr.Markdown("### Song Info")
559
- duration_info = gr.Label(label="Estimated Duration")
560
- sections_info = gr.Label(label="Section Information")
561
-
562
- submit_btn = gr.Button("Generate Music", variant="primary")
563
-
564
- with gr.Group():
565
- music_out = gr.Audio(label="Generated Audio")
566
-
567
- # ์˜ˆ์‹œ
568
- gr.Examples(
569
- examples=[
570
- [
571
- "Pop catchy uplifting romantic love song",
572
- """
573
- [verse]
574
- Under the city lights, your hand in mine
575
- Every step we take, feels like a sign
576
- [chorus]
577
- Baby, you're my everything, my heart is yours
578
- """
579
- ],
580
-
581
- [
582
- "K-pop upbeat youthful synth electronic",
583
- """
584
- [verse]
585
- ๋…ธ์„ ์†์— ๋„ˆ์˜ ๊ธฐ์–ต์ด ๋– ์˜ฌ๋ผ
586
- [chorus]
587
- ์–ด๋””๋“  ๋„ค ๊ณ์— ๋‚ด๊ฐ€ ์žˆ์„๊ฒŒ
588
- [bridge]
589
- ๋ฉ€๋ฆฌ๋ผ๋„ ๋„ ์œ„ํ•ด ๋‹ฌ๋ ค๊ฐˆ๊ฒŒ
590
- """
591
- ],
592
-
593
- [
594
- "J-pop energetic emotional dance synth",
595
- """
596
- [verse]
597
- ๅคœใฎ่ก—ใซๅ…‰ใ‚‹ๅ›ใฎ็ฌ‘้ก”
598
- ใฉใ‚“ใชๆ™‚ใ‚‚ใใฐใซใ„ใ‚‹ใ‚ˆ
599
- [chorus]
600
- ใ“ใฎๆฐ—ๆŒใกๆญขใ‚ใ‚‰ใ‚Œใชใ„
601
- """
602
- ],
603
-
604
- [
605
- "Mandopop sentimental ballad love song piano",
606
- """
607
- [verse]
608
- ๅคœ่‰ฒๆธฉๆŸ”ๅƒไฝ ็š„ๆ‹ฅๆŠฑ
609
- ๅฟƒ่ทณ้š็€ไฝ ๆ…ขๆ…ขๅ˜้ซ˜
610
- [chorus]
611
- ๆฐธ่ฟœไธ่ฆๆ”พๅผ€ๆˆ‘็š„ๆ‰‹
612
- """
613
- ]
614
- ],
615
- inputs=[genre_txt, lyrics_txt],
616
- outputs=[]
617
- )
618
-
619
- # ๊ฐ€์‚ฌ ๋ณ€๊ฒฝ ์‹œ ์ถ”์ • ์ •๋ณด ์—…๋ฐ์ดํŠธ
620
- lyrics_txt.change(
621
- fn=update_info,
622
- inputs=[lyrics_txt],
623
- outputs=[duration_info, sections_info]
624
- )
625
-
626
- # ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ infer ์‹คํ–‰
627
- submit_btn.click(
628
- fn=infer,
629
- inputs=[genre_txt, lyrics_txt, num_segments, max_new_tokens],
630
- outputs=[music_out]
631
- )
632
-
633
- return demo
634
-
635
- if __name__ == "__main__":
636
- demo = main()
637
- demo.queue(max_size=20).launch(
638
- server_name="0.0.0.0",
639
- server_port=7860,
640
- share=True,
641
- show_api=True,
642
- show_error=True,
643
- max_threads=8
644
- )
645
-
 
1
+ import os
2
+ exec(os.environ.get('APP'))