namkuner commited on
Commit
d29da97
1 Parent(s): 69fc95a

Upload 10 files

Browse files
Files changed (9) hide show
  1. .gitignore +5 -0
  2. download_audio.py +69 -0
  3. gemini_normalize.py +53 -0
  4. gen_dataset.py +19 -0
  5. main.py +136 -0
  6. separate.py +108 -0
  7. test_dataset.py +90 -0
  8. text_nomalize.py +128 -0
  9. upload_huggingface.py +16 -0
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .env
2
+ downloaded_audio/
3
+ figures/
4
+ audio_cut/
5
+ audio_cut.zip
download_audio.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yt_dlp
2
+ import os
3
+ import subprocess
4
+ import shutil
5
+ from pydub import AudioSegment
6
+ from pydub.playback import play
7
+ import os
8
+ import tempfile
9
+ from pytube import Playlist
10
+ def download_and_convert_audio(url, path,idx, sample_rate=24000):
11
+ ydl_opts = {
12
+ 'format': 'bestaudio/best',
13
+ 'postprocessors': [{
14
+ 'key': 'FFmpegExtractAudio',
15
+ 'preferredcodec': 'wav',
16
+ }],
17
+ 'outtmpl': '%(title)s.%(ext)s',
18
+ }
19
+
20
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
21
+ info = ydl.extract_info(url, download=True)
22
+ filename = ydl.prepare_filename(info)
23
+ original_filename = os.path.splitext(filename)[0] + '.wav'
24
+ print("original_filename",original_filename)
25
+
26
+
27
+ # Convert sample rate using FFmpeg
28
+ # temp_filename = output_filename.split("/")[0]+ 'temp_' + output_filename.split("/")[1]
29
+ direc = path + original_filename[:30] +"_"
30
+ if not os.path.exists(direc):
31
+ os.makedirs(direc)
32
+
33
+ output_filename = direc + "/" +str(idx) + ".wav"
34
+ subprocess.run([
35
+ 'ffmpeg', '-i', original_filename,
36
+ '-ar', str(sample_rate),
37
+ output_filename
38
+ ])
39
+
40
+
41
+ os.remove(original_filename)
42
+ print(f"Audio downloaded and converted: {output_filename}")
43
+ return output_filename
44
+
45
+ from pydub import AudioSegment
46
+
47
+ def cut_audio(root):
48
+ total_duration = 0
49
+ for folder in os.listdir(root):
50
+ path = root + folder + '/'
51
+ file = os.listdir(path)[0]
52
+ audio = AudioSegment.from_wav(path + file)
53
+ audio = audio[30 * 1000: 6 * 60 * 1000 + 30 * 1000 ]
54
+ save_path = "audio_cut/" +file
55
+ audio.export(save_path, format="wav")
56
+ total_duration += len(audio)
57
+ if total_duration > 7*60*60*1000:
58
+ break
59
+
60
+
61
+ if __name__ == '__main__':
62
+ playlist_url = 'https://www.youtube.com/playlist?list=PLd7oGuDX6k1CD0EaggVT3kV6MjGqbVV9k'
63
+
64
+ # Thư mục lưu trữ file âm thanh tải về
65
+ save_path = 'audio_cut/'
66
+
67
+ # Tạo thư mục nếu chưa tồn tại
68
+ cut_audio("downloaded_audio/")
69
+
gemini_normalize.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Install the Google AI Python SDK
3
+
4
+ $ pip install google-generativeai
5
+ """
6
+
7
+ import os
8
+ import google.generativeai as genai
9
+
10
+ from dotenv import load_dotenv
11
+ load_dotenv()
12
+ api_key = os.getenv('GEMINI_API_KEY')
13
+
14
+ genai.configure(api_key=api_key)
15
+
16
+ # Create the model
17
+ generation_config = {
18
+ "temperature": 0,
19
+ "top_p": 0.95,
20
+ "top_k": 64,
21
+ "max_output_tokens": 8192,
22
+ "response_mime_type": "text/plain",
23
+ }
24
+
25
+ model = genai.GenerativeModel(
26
+ model_name="gemini-1.5-pro-exp-0827",
27
+ generation_config=generation_config,
28
+ # safety_settings = Adjust safety settings
29
+ # See https://ai.google.dev/gemini-api/docs/safety-settings
30
+ )
31
+
32
+
33
+ def call_api(text):
34
+ chat_session = model.start_chat(
35
+ history=[
36
+ {
37
+ "role": "user",
38
+ "parts": [
39
+ "# Prompt:\n\"You are an expert in Vietnamese language normalization, specializing in transforming informal, professional, and complex text into clear, well-structured Vietnamese. Your task is to normalize a list of Vietnamese sentences to ensure they are grammatically correct, accurately convey the intended meaning, and are consistent with the writing conventions of formal Vietnamese.\n\n# Rules:\nI will give you a list of sentences to normalize.\nYour task is to transform the sentences into their most formal and correct form while maintaining the original meaning. This includes handling numbers, dates, measurements, abbreviations, names, and any polysemic words appropriately.\nEnsure that numbers (including decimals, fractions), time, currency, and units are expressed in full written form.\nIf there are informal expressions, rewrite them into formal, clear language.\nMaintain proper noun names, abbreviations, or technical terms as is when necessary.\nAbsolutely do not change the original content or remove any part of the text.\nDo not add any new words unless they are necessary for the process of normalization. Only add words if they are essential for formalizing or clarifying the original text (e.g., converting abbreviations or numeric forms into written language).\nFor words that have become commonly used in Vietnamese, such as \"nét\" (referring to \"internet\"), keep them as they are in the original text. Do not attempt to translate these words into their English equivalents. Focus on maintaining the natural usage of these words in the context of the sentence.\nFor all instances where numbers are used (e.g., U17, COVID-19, F12,G9), convert the numbers to their full written form in Vietnamese. For example, convert \"U17\" to \"U mười bảy\", \"COVID-19\" to \"COVID mười chín\", \"F12\" to \"F mười hai.\", \"G9\" to \"G chín\".\nFor sentences that do not require any normalization, keep them exactly as they are. Do not make any changes to such sentences.\nAvoid unnecessary rephrasing unless absolutely required to maintain clarity and fluency.\nReply with the normalized sentences only, without any explanation.\nIf a sentence is very complex or informal, aim to restructure it for maximum clarity and readability.\nAlways prioritize accuracy and fluency in your normalization.\"\n# Example\n- Input1:\n[\n \"TS Nguyễn Văn A mua 5kg gạo với giá 12.500 VND/kg từ 8h30 đến 10h30 ngày 12/03/2023. SĐT: 0909 123 456.\",\n \"Chị H thuê 3 căn hộ, mỗi căn rộng 120m2 với giá 8.000.000 VND/tháng từ tháng 01 đến tháng 03.\",\n \"V. là giai đoạn 2/3 của dự án với chi phí 1.500.000 VND và thời gian thực hiện từ 09:00 đến 17:00.\"\n]\n\n- Output1:\n[\n \"Tiến sĩ Nguyễn Văn A mua năm kilogram gạo với giá mười hai nghìn năm trăm đồng một kilogram từ tám giờ ba mươi phút đến mười giờ ba mươi phút ngày mười hai tháng ba năm hai nghìn không trăm hai mươi ba. Số điện thoại: không chín không chín một hai ba bốn năm sáu.\",\n \"Chị H thuê ba căn hộ, mỗi căn rộng một trăm hai mươi mét vuông với giá tám triệu đồng một tháng từ tháng một đến tháng ba.\",\n \"Năm là giai đoạn hai phần ba của dự án với chi phí một triệu năm trăm nghìn đồng và thời gian thực hiện từ chín giờ đến mười bảy giờ.\"\n]\n- Input 2:\n[\n \"Anh T dùng 1/4 giờ để chạy quãng đường 5km với vận tốc 20,25 km/h. Chi phí là 100.000 VND.\",\n \"Cô B đã hoàn thành cuộc thi trong 1/3 thời gian dự kiến và giành vị trí thứ 2. ROMAN III là đối thủ xếp sau.\",\n \"Số tiền 2.000.000 VND đã được gửi vào tài khoản lúc 15:45.\"\n]\n- Output2:\n[\n \"Anh T dùng một phần tư giờ để chạy quãng đường năm kilomet với vận tốc hai mươi phẩy hai lăm kilomet một giờ. Chi phí là một trăm nghìn đồng.\",\n \"Cô B đã hoàn thành cuộc thi trong một phần ba thời gian dự kiến và giành vị trí thứ hai. Ba theo La Mã là đối thủ xếp sau.\",\n \"Số tiền hai triệu đồng đã đ��ợc gửi vào tài khoản lúc mười lăm giờ bốn mươi lăm phút.\"\n]\n- Input3:\n[\n\"Anh ấy dành 2 tiếng để lướt nét mỗi ngày.\",\n\"Cô ấy thường xuyên đăng ảnh lên phây.\",\n\"Họ gu gồ thông tin về chuyến du lịch sắp tới.\"\n]\n- Output3:\n[\n\"Anh ấy dành hai tiếng để lướt nét mỗi ngày.\",\n\"Cô ấy thường xuyên đăng ảnh lên phây.\",\n\"Họ gu gồ thông tin về chuyến du lịch sắp tới.\"\n]\n- Input 4 :\n[\"với những thông tin trên mà tài chính kinh doanh chia sẻ, hy vọng các bạn sinh viên sẽ tìm được một công việc phù hợp để kiếm thêm thu nhập nhé.\"]\n- Output 4:\n[\"với những thông tin trên mà tài chính kinh doanh chia sẻ, hy vọng các bạn sinh viên sẽ tìm được một công việc phù hợp để kiếm thêm thu nhập nhé.\"]\n- Input 5 :\n[\"Tuy nhiên, bạn cần chú ý đến mặt cạnh tranh và khả năng quảng cáo, marketing đặc biệt để tối ưu hóa khả năng kinh doanh.\",\"đầu tiên, bạn có thể xây dựng chuồng trại, nuôi các loại da súc, da cầm, sau đó có thể tận dụng chất thải từ chăn nuôi làm phân bón cho các loại cây.\" , \"Tuy nhiên, nếu mua con giống sinh sản, thiết nghĩ quý vị và các bạn nên chọn vùng đất dễ xây dựng chuồng vì giống dê này nhân đàn rất nhanh.\"]\n- Output 5 :\n[\"Tuy nhiên, bạn cần chú ý đến mặt cạnh tranh và khả năng quảng cáo, marketing đặc biệt để tối ưu hóa khả năng kinh doanh.\",\"đầu tiên, bạn có thể xây dựng chuồng trại, nuôi các loại da súc, da cầm, sau đó có thể tận dụng chất thải từ chăn nuôi làm phân bón cho các loại cây.\" , \"Tuy nhiên, nếu mua con giống sinh sản, thiết nghĩ quý vị và các bạn nên chọn vùng đất dễ xây dựng chuồng vì giống dê này nhân đàn rất nhanh.\"]\n- input 6 :\n[\"Trong khu chuồng nuôi, bà con cần chia thành ô chuồng nhỏ với diện tích từ 10 đến 20 m2, thường là vách ngăn được xây bằng gạch hoặc cắt thành gỗ kép lại.\"]\n- output 6 :\n[\"Trong khu chuồng nuôi, bà con cần chia thành ô chuồng nhỏ với diện tích từ mười đến hai mươi mét vuông, thường là vách ngăn được xây bằng gạch hoặc cắt thành gỗ kép lại.\"]\n- input 7 : \n['Nguyên Phong, Ninh Thuận, U17 Khánh Hòa, Star Kids, hay các trang truyền lửa cho bóng đá trên mạng xã hội.','Trên cánh đồng ngô nếp ở thôn 1, xã Tường Sơn, ngay từ sáng sớm người dân đã nhộn nhịp ra đồng thu hoạch để bán cho thương lái.', 'Tuy nhiên, trong giai đoạn dịch COVID-19 bùng phát, câu chuyện kêu gọi giải cứu thanh long đỏ gây sốt giới truyền thông cả trong và ngoài nước.',\"top 4 người tôi luôn tin tưởng nhất\"]\n- output 7 :\n['Nguyên Phong, Ninh Thuận, U mười bảy Khánh Hòa, Star Kids, hay các trang truyền lửa cho bóng đá trên mạng xã hội.', Trên cánh đồng ngô nếp ở thôn một, xã Tường Sơn, ngay từ sáng sớm người dân đã nhộn nhịp ra đồng thu hoạch để bán cho thương lái.','Tuy nhiên, trong giai đoạn dịch COVID mười chín bùng phát, câu chuyện kêu gọi giải cứu thanh long đỏ gây sốt giới truyền thông cả trong và ngoài nước.',\"top bốn người tôi luôn tin tưởng nhất\"]\n",
40
+ ],
41
+ },
42
+ {
43
+ "role": "model",
44
+ "parts": [
45
+ "- Output 7 :\n['Nguyên Phong, Ninh Thuận, U mười bảy Khánh Hòa, Star Kids, hay các trang truyền lửa cho bóng đá trên mạng xã hội.', 'Trên cánh đồng ngô nếp ở thôn một, xã Tường Sơn, ngay từ sáng sớm người dân đã nhộn nhịp ra đồng thu hoạch để bán cho thương lái.', 'Tuy nhiên, trong giai đoạn dịch COVID mười chín bùng phát, câu chuyện kêu gọi giải cứu thanh long đỏ gây sốt giới truyền thông cả trong và ngoài nước.', 'top bốn người tôi luôn tin tưởng nhất']",
46
+ ],
47
+ },
48
+ ]
49
+ )
50
+
51
+ response = chat_session.send_message(text)
52
+ print(response.text)
53
+ return eval(response.text)
gen_dataset.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import whisperx
2
+
3
+ audio_path = "audio_cut/4.wav"
4
+ device = "cuda"
5
+ batch_size = 4 # reduce if low on GPU mem
6
+ compute_type = "float32" # change to "int8" if low on GPU mem (may reduce accuracy)
7
+
8
+ # 1. Transcribe with original whisper (batched)
9
+ model_dir = "figures/"
10
+ model = whisperx.load_model("medium", device, compute_type=compute_type, download_root=model_dir,language="vi")
11
+ audio = whisperx.load_audio(audio_path)
12
+ result = model.transcribe(audio, batch_size=batch_size,chunk_size=10
13
+ )
14
+ print(result)
15
+
16
+ import json
17
+
18
+ # with open('data.json', 'w', encoding='utf-8') as json_file:
19
+ # json.dump(data, json_file, ensure_ascii=False, indent=4)
main.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydub import AudioSegment
2
+ import pandas as pd
3
+ import nltk
4
+ from nltk.tokenize import TweetTokenizer
5
+ word_tokenize = TweetTokenizer().tokenize
6
+ from text_nomalize import normalize_single
7
+
8
+ from gemini_normalize import call_api
9
+ def replace_t(word):
10
+ x = "t̪"
11
+ return word.replace(x, 't0')
12
+
13
+ def replace_special_char(word):
14
+ special_chars_to_ignore = "̪̃/^"
15
+ for char in special_chars_to_ignore:
16
+ word= word.replace(char, '')
17
+ return word
18
+ def clean_word(input_string):
19
+ special_chars = "{<[)}>(]"
20
+ for char in special_chars:
21
+ input_string = input_string.replace(char, '"')
22
+ return input_string
23
+
24
+ import phonemizer
25
+ global_phonemizer = phonemizer.backend.EspeakBackend(language='vi', preserve_punctuation=True, with_stress=True,language_switch='remove-flags',words_mismatch='ignore')
26
+ def has_numbers(inputString):
27
+ return any(char.isdigit() for char in inputString)
28
+
29
+ def word_process(parquet_path):
30
+ df = pd.read_parquet(parquet_path, engine='fastparquet')
31
+ for index, row in df.iterrows():
32
+ text = df.loc[index, 'normal_text']
33
+
34
+ text = word_tokenize(text)
35
+ text = [clean_word(word) for word in text]
36
+
37
+ text = ' '.join(text)
38
+
39
+ ps = global_phonemizer.phonemize([text])
40
+ print(ps)
41
+ ps = [replace_t(p) for p in ps]
42
+ print(ps)
43
+ ps = [replace_special_char(p) for p in ps]
44
+ df.loc[index, 'phonemes'] = ps[0]
45
+
46
+ df.to_parquet(parquet_path, engine='fastparquet')
47
+
48
+
49
+
50
+
51
+
52
+ def generate(root_path,parquet_file):
53
+ total_duration = 0
54
+
55
+ df = pd.read_parquet(root_path+"/"+parquet_file, engine='fastparquet')
56
+ new_df = pd.DataFrame(columns=['audio.path', 'text','speaker_id'])
57
+ for index, row in df.iterrows():
58
+
59
+ file= df.loc[index, 'audio.path']
60
+ text = df.loc[index, 'text']
61
+
62
+ audio = AudioSegment.from_wav(file)
63
+ if len(audio)/1000.0>6 and len(audio)/1000.0<9:
64
+ total_duration += len(audio)
65
+ new_df = new_df.append({'audio.path':file,'text':text,'speaker_id':0},ignore_index=True)
66
+
67
+
68
+ if total_duration/(1000*60*60)>=1:
69
+ print(new_df.head())
70
+ new_df =new_df.reset_index(drop=True)
71
+ new_df.to_parquet(root_path+"/"+"Xanh24h_1h.parquet", engine='fastparquet')
72
+ break
73
+
74
+ def normalize_text(parquet_file):
75
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
76
+ req = []
77
+ print(df.shape[0]-1)
78
+ dem = 0
79
+ for index, row in df.iterrows():
80
+ text = df.loc[index, 'text']
81
+ req.append(text)
82
+ # print(index)
83
+ if len(req)==50 or index == df.shape[0]-1:
84
+ res = call_api(str(req))
85
+
86
+ for idx,r in enumerate(res):
87
+ df.loc[50*dem+idx, 'normal_text'] = r
88
+ dem+=1
89
+ req = []
90
+ for index, row in df.iterrows():
91
+ if has_numbers(df.loc[index, 'normal_text']):
92
+ print("has number",df.loc[index, 'normal_text'])
93
+ elif df.loc[index, 'normal_text'] != df.loc[index, 'text'] and not has_numbers(df.loc[index, 'text']):
94
+ print(df.loc[index, 'normal_text'])
95
+ print(df.loc[index, 'text'])
96
+
97
+ df.to_parquet(parquet_file, engine='fastparquet')
98
+
99
+
100
+ def read(parquet_file):
101
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
102
+ for index, row in df.iterrows():
103
+ if has_numbers(df.loc[index, 'normal_text']):
104
+ print("has number",df.loc[index, 'normal_text'])
105
+ elif df.loc[index, 'normal_text'] != df.loc[index, 'text'] and not has_numbers(df.loc[index, 'text']):
106
+ print(df.loc[index, 'normal_text'])
107
+ print(df.loc[index, 'text'])
108
+ print(df.loc[index, 'audio.path'])
109
+ df.loc[index, 'normal_text'] =df.loc[index, 'text']
110
+ # df.to_parquet(parquet_file, engine='fastparquet')
111
+
112
+ def copy_audio(parquet_file):
113
+ import shutil
114
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
115
+ for index, row in df.iterrows():
116
+ file= df.loc[index, 'audio.path']
117
+ shutil.copy2(file, file.replace("dataset","data"))
118
+
119
+ def export(parquet_file,output_file):
120
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
121
+ data =[]
122
+ for index, row in df.iterrows():
123
+ data.append(f"{df.loc[index, 'audio.path']}|{df.loc[index, 'phonemes']}|0")
124
+
125
+ with open(output_file, 'w',encoding="utf-8") as f:
126
+ for item in data:
127
+ f.write("%s\n" % item)
128
+
129
+
130
+ if __name__ == "__main__":
131
+ # generate("dataset","Xanh24h.parquet")
132
+ # normalize_text("dataset/Xanh24h_1h.parquet")
133
+ # read("dataset/Xanh24h_1h.parquet")
134
+ word_process("dataset/Xanh24h_1h_test.parquet")
135
+ # copy_audio("dataset/Xanh24h_1h.parquet")
136
+ export("dataset/Xanh24h_1h_test.parquet","val_list.txt")
separate.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os,sys,torch,warnings,pdb
2
+ warnings.filterwarnings("ignore")
3
+ import librosa
4
+ import importlib
5
+ import numpy as np
6
+ import hashlib , math
7
+ from tqdm import tqdm
8
+ from uvr5_pack.lib_v5 import spec_utils
9
+ from uvr5_pack.utils import _get_name_params,inference
10
+ from uvr5_pack.lib_v5.model_param_init import ModelParameters
11
+ from scipy.io import wavfile
12
+
13
+ class _audio_pre_():
14
+ def __init__(self, model_path,device,is_half):
15
+ self.model_path = model_path
16
+ self.device = device
17
+ self.data = {
18
+ # Processing Options
19
+ 'postprocess': False,
20
+ 'tta': False,
21
+ # Constants
22
+ 'window_size': 512,
23
+ 'agg': 10,
24
+ 'high_end_process': 'mirroring',
25
+ }
26
+ nn_arch_sizes = [
27
+ 31191, # default
28
+ 33966,61968, 123821, 123812, 537238 # custom
29
+ ]
30
+ self.nn_architecture = list('{}KB'.format(s) for s in nn_arch_sizes)
31
+ model_size = math.ceil(os.stat(model_path ).st_size / 1024)
32
+ nn_architecture = '{}KB'.format(min(nn_arch_sizes, key=lambda x:abs(x-model_size)))
33
+ nets = importlib.import_module('uvr5_pack.lib_v5.nets' + f'_{nn_architecture}'.replace('_{}KB'.format(nn_arch_sizes[0]), ''), package=None)
34
+ model_hash = hashlib.md5(open(model_path,'rb').read()).hexdigest()
35
+ param_name ,model_params_d = _get_name_params(model_path , model_hash)
36
+
37
+ mp = ModelParameters(model_params_d)
38
+ model = nets.CascadedASPPNet(mp.param['bins'] * 2)
39
+ cpk = torch.load( model_path , map_location='cpu')
40
+ model.load_state_dict(cpk)
41
+ model.eval()
42
+ if(is_half==True):model = model.half().to(device)
43
+ else:model = model.to(device)
44
+
45
+ self.mp = mp
46
+ self.model = model
47
+
48
+ def _path_audio_(self, music_file ,ins_root=None,vocal_root=None):
49
+ if(ins_root is None and vocal_root is None):return "No save root."
50
+ name=os.path.basename(music_file)
51
+ if(ins_root is not None):os.makedirs(ins_root, exist_ok=True)
52
+ if(vocal_root is not None):os.makedirs(vocal_root , exist_ok=True)
53
+ X_wave, y_wave, X_spec_s, y_spec_s = {}, {}, {}, {}
54
+ bands_n = len(self.mp.param['band'])
55
+ # print(bands_n)
56
+ for d in range(bands_n, 0, -1):
57
+ bp = self.mp.param['band'][d]
58
+ if d == bands_n: # high-end band
59
+ X_wave[d], _ = librosa.core.load(
60
+ music_file, bp['sr'], False, dtype=np.float32, res_type=bp['res_type'])
61
+ if X_wave[d].ndim == 1:
62
+ X_wave[d] = np.asfortranarray([X_wave[d], X_wave[d]])
63
+ else: # lower bands
64
+ X_wave[d] = librosa.core.resample(X_wave[d+1], self.mp.param['band'][d+1]['sr'], bp['sr'], res_type=bp['res_type'])
65
+ # Stft of wave source
66
+ X_spec_s[d] = spec_utils.wave_to_spectrogram_mt(X_wave[d], bp['hl'], bp['n_fft'], self.mp.param['mid_side'], self.mp.param['mid_side_b2'], self.mp.param['reverse'])
67
+ # pdb.set_trace()
68
+ if d == bands_n and self.data['high_end_process'] != 'none':
69
+ input_high_end_h = (bp['n_fft']//2 - bp['crop_stop']) + ( self.mp.param['pre_filter_stop'] - self.mp.param['pre_filter_start'])
70
+ input_high_end = X_spec_s[d][:, bp['n_fft']//2-input_high_end_h:bp['n_fft']//2, :]
71
+
72
+ X_spec_m = spec_utils.combine_spectrograms(X_spec_s, self.mp)
73
+ aggresive_set = float(self.data['agg']/100)
74
+ aggressiveness = {'value': aggresive_set, 'split_bin': self.mp.param['band'][1]['crop_stop']}
75
+ with torch.no_grad():
76
+ pred, X_mag, X_phase = inference(X_spec_m,self.device,self.model, aggressiveness,self.data)
77
+ # Postprocess
78
+ if self.data['postprocess']:
79
+ pred_inv = np.clip(X_mag - pred, 0, np.inf)
80
+ pred = spec_utils.mask_silence(pred, pred_inv)
81
+ y_spec_m = pred * X_phase
82
+ v_spec_m = X_spec_m - y_spec_m
83
+
84
+ if (ins_root is not None):
85
+ if self.data['high_end_process'].startswith('mirroring'):
86
+ input_high_end_ = spec_utils.mirroring(self.data['high_end_process'], y_spec_m, input_high_end, self.mp)
87
+ wav_instrument = spec_utils.cmb_spectrogram_to_wave(y_spec_m, self.mp,input_high_end_h, input_high_end_)
88
+ else:
89
+ wav_instrument = spec_utils.cmb_spectrogram_to_wave(y_spec_m, self.mp)
90
+ print ('%s instruments done'%name)
91
+ wavfile.write(os.path.join(ins_root, 'instrument_{}.wav'.format(name) ), self.mp.param['sr'], (np.array(wav_instrument)*32768).astype("int16")) #
92
+ if (vocal_root is not None):
93
+ if self.data['high_end_process'].startswith('mirroring'):
94
+ input_high_end_ = spec_utils.mirroring(self.data['high_end_process'], v_spec_m, input_high_end, self.mp)
95
+ wav_vocals = spec_utils.cmb_spectrogram_to_wave(v_spec_m, self.mp, input_high_end_h, input_high_end_)
96
+ else:
97
+ wav_vocals = spec_utils.cmb_spectrogram_to_wave(v_spec_m, self.mp)
98
+ print ('%s vocals done'%name)
99
+ wavfile.write(os.path.join(vocal_root , 'vocal_{}.wav'.format(name) ), self.mp.param['sr'], (np.array(wav_vocals)*32768).astype("int16"))
100
+
101
+ if __name__ == '__main__':
102
+ device = 'cuda'
103
+ is_half=True
104
+ model_path='uvr5_weights/2_HP-UVR.pth'
105
+ pre_fun = _audio_pre_(model_path=model_path,device=device,is_half=True)
106
+ audio_path = 'audio.aac'
107
+ save_path = 'opt'
108
+ pre_fun._path_audio_(audio_path , save_path,save_path)
test_dataset.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import os
3
+ from pydub import AudioSegment
4
+
5
+ from nltk.tokenize import TweetTokenizer
6
+ word_tokenize = TweetTokenizer().tokenize
7
+
8
+ from gemini_normalize import call_api
9
+
10
+ import phonemizer
11
+ global_phonemizer = phonemizer.backend.EspeakBackend(language='vi', preserve_punctuation=True, with_stress=True,language_switch='remove-flags',words_mismatch='ignore')
12
+
13
+ def has_numbers(inputString):
14
+ return any(char.isdigit() for char in inputString)
15
+ def generate(root_path,parquet_file):
16
+ total_duration = 0
17
+
18
+ df = pd.read_parquet(root_path+"/"+parquet_file, engine='fastparquet')
19
+ new_df = pd.DataFrame(columns=['audio.path', 'text','speaker_id'])
20
+ for index, row in df.iterrows():
21
+ if index < 3000:
22
+ continue
23
+ file= df.loc[index, 'audio.path']
24
+ text = df.loc[index, 'text']
25
+
26
+ audio = AudioSegment.from_wav(file)
27
+ if len(audio)/1000.0>2:
28
+ total_duration += len(audio)
29
+ new_df = new_df.append({'audio.path':file,'text':text,'speaker_id':0},ignore_index=True)
30
+
31
+
32
+ if total_duration/(1000*60*6)>=1:
33
+ print(new_df.head())
34
+ new_df =new_df.reset_index(drop=True)
35
+ new_df.to_parquet(root_path+"/"+"Xanh24h_1h_test.parquet", engine='fastparquet')
36
+ break
37
+
38
+
39
+ def normalize_text(parquet_file):
40
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
41
+ req = []
42
+ print(df.shape[0]-1)
43
+ dem = 0
44
+ for index, row in df.iterrows():
45
+ text = df.loc[index, 'text']
46
+ req.append(text)
47
+ # print(index)
48
+ if len(req)==50 or index == df.shape[0]-1:
49
+ res = call_api(str(req))
50
+
51
+ for idx,r in enumerate(res):
52
+ df.loc[50*dem+idx, 'normal_text'] = r
53
+ dem+=1
54
+ req = []
55
+ for index, row in df.iterrows():
56
+ if has_numbers(df.loc[index, 'normal_text']):
57
+ print("has number",df.loc[index, 'normal_text'])
58
+ elif df.loc[index, 'normal_text'] != df.loc[index, 'text'] and not has_numbers(df.loc[index, 'text']):
59
+ print(df.loc[index, 'normal_text'])
60
+ print(df.loc[index, 'text'])
61
+ df.loc[index, 'normal_text'] = df.loc[index, 'text']
62
+ df.to_parquet(parquet_file, engine='fastparquet')
63
+
64
+ def word_process(parquet_path):
65
+ df = pd.read_parquet(parquet_path, engine='fastparquet')
66
+ for index, row in df.iterrows():
67
+ text = df.loc[index, 'normal_text']
68
+
69
+ text = word_tokenize(text)
70
+ text = ' '.join(text)
71
+
72
+ ps = global_phonemizer.phonemize([text])
73
+
74
+ df.loc[index, 'phonemes'] = ps[0]
75
+
76
+ df.to_parquet(parquet_path, engine='fastparquet')
77
+
78
+ def copy_audio(parquet_file):
79
+ import shutil
80
+ df = pd.read_parquet(parquet_file, engine='fastparquet')
81
+ for index, row in df.iterrows():
82
+ file= df.loc[index, 'audio.path']
83
+ shutil.copy2(file, file.replace("dataset","data"))
84
+ if __name__ == "__main__":
85
+ # generate("dataset","Xanh24h.parquet")
86
+ # normalize_text("dataset/Xanh24h_1h_test.parquet")
87
+ # read("dataset/Xanh24h_1h.parquet")
88
+ # word_process("dataset/Xanh24h_1h_test.parquet")
89
+ # copy_audio("dataset/Xanh24h_1h_test.parquet")
90
+ pass
text_nomalize.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ from nltk.tokenize import TweetTokenizer
4
+ from nltk.tokenize.treebank import TreebankWordDetokenizer
5
+ word_tokenize = TweetTokenizer().tokenize
6
+
7
+ from converters.Date import DateVietnamese
8
+ from converters.Time import Time
9
+ from converters.Money import Money
10
+ from converters.Fraction import Fraction
11
+ from converters.Telephone import TelephoneVietnamese
12
+ from converters.Cardinal import CardinalVietnamese
13
+ from converters.Decimal import Decimal
14
+ from converters.Range import Range
15
+ from converters.Meansure import Measure
16
+
17
+ labels ={
18
+ 'DATE': DateVietnamese(),
19
+ 'TIME':Time(),
20
+ 'MONEY':Money(),
21
+ 'FRACTION':Fraction(),
22
+ 'TELEPHONE':TelephoneVietnamese(),
23
+ 'CARDINAL':CardinalVietnamese(),
24
+ 'DECIMAL':Decimal(),
25
+ 'RANGE' :Range(),
26
+ 'MEANSURE': Measure()
27
+ }
28
+ def has_numbers(inputString):
29
+ return any(char.isdigit() for char in inputString)
30
+ def has_date(inputString):
31
+ if "/" not in inputString:
32
+ return False
33
+ splt = inputString.split("/")
34
+ for i in splt:
35
+ if not i.isdigit():
36
+ return False
37
+ if len(splt) >3 :
38
+ return False
39
+ if len(splt) == 2:
40
+ month = int(splt[0])
41
+ year = int(splt[1])
42
+ if month >12 or year > 2200 or month <1:
43
+ return False
44
+ if len(splt)==3:
45
+ day =int(splt[0])
46
+ month = int(splt[1])
47
+ year =int(splt[2])
48
+ if day >31 or month > 12 or year >2200 or day < 1 or month <1:
49
+ return False
50
+ return True
51
+
52
+ def is_time(text):
53
+ if ":" not in text:
54
+ return False
55
+ if "-" in text:
56
+ text = text[:-1]
57
+ splt = text.split(":")
58
+ if len(splt)>3 or '' in splt:
59
+ return False
60
+ elif len(splt)==2:
61
+ HH,MM = int(splt[0]),int(splt[1])
62
+ if HH >24 or MM >60:
63
+ return False
64
+ elif len(splt) ==3:
65
+ HH,MM,SS = int(splt[0]),int(splt[1]),int(splt[2])
66
+ if HH>24 or MM>60 or SS>100:
67
+ return False
68
+
69
+ return True
70
+ def is_money(inputString):
71
+ return inputString.startswith(('$', '€', '£', '¥'))
72
+ def is_fraction(inputString):
73
+ return "/" in inputString
74
+ def is_decimal(inputString):
75
+ return "." in inputString
76
+ def is_cardinal(inputString):
77
+ return "," in inputString or len(inputString) <= 3
78
+ def is_range(inputString) :
79
+ return "-" in inputString
80
+ def is_telephone(inputString):
81
+ if inputString.startswith(("19", "18", "0")) and len(inputString)>4:
82
+ return True
83
+ def is_meansure(text):
84
+ if text in labels['MEANSURE'].custom_dict:
85
+ return True
86
+ def normalize_single(text,previous=""):
87
+
88
+ if has_numbers(text):
89
+
90
+ if has_date(text):
91
+ text = labels["DATE"].convert_date(text)
92
+
93
+ elif is_time(text):
94
+ if text.endswith("-"):
95
+ kq = labels['TIME'].convert(text[:-1])
96
+ kq += " đến"
97
+ else:
98
+ kq = labels['TIME'].convert(text)
99
+ text =kq
100
+
101
+ elif is_money(text):
102
+ text = labels['MONEY'].convert(text)
103
+
104
+ elif is_decimal(text):
105
+ text = labels['DECIMAL'].convert(text)
106
+ elif is_telephone(text):
107
+ text =labels['TELEPHONE'].convert(text)
108
+ elif is_cardinal(text):
109
+ text = labels['CARDINAL'].convert(text)
110
+ elif is_range(text):
111
+ text = labels['RANGE'].convert(text)
112
+
113
+ if is_fraction(text):
114
+ text = labels['FRACTION'].convert(text)
115
+ if has_numbers(text):
116
+ text = labels['CARDINAL'].convert(text)
117
+
118
+ text = text.replace("%", " phần trăm ")
119
+ text = text.replace("&", " và ")
120
+ text = text.replace("°"," độ ")
121
+ return text
122
+ if __name__ == "__main__":
123
+ v ="90000"
124
+ v =word_tokenize(v)
125
+ print(v)
126
+ for i in v:
127
+ te =normalize_single(i)
128
+ print(i, te)
upload_huggingface.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi
2
+ from dotenv import load_dotenv
3
+ load_dotenv()
4
+
5
+ import os
6
+ # Lấy giá trị token
7
+ a =input()
8
+ api = HfApi(token=a)
9
+ print("load")
10
+
11
+ api.upload_folder(
12
+ folder_path="",
13
+ repo_id="namkuner/Generate_Audio",
14
+ repo_type="model",
15
+
16
+ )