Spaces:
Runtime error
Runtime error
update
Browse files
app.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import json
|
2 |
import os
|
|
|
3 |
import warnings
|
4 |
|
5 |
import gradio as gr
|
@@ -12,6 +13,7 @@ from loguru import logger
|
|
12 |
warnings.filterwarnings("ignore")
|
13 |
|
14 |
NUM_TAR_FILES = 115
|
|
|
15 |
HF_PATH_TO_DATASET = "litagin/Galgame_Speech_SER_16kHz"
|
16 |
|
17 |
hf_token = os.getenv("HF_TOKEN")
|
@@ -77,15 +79,16 @@ def _load_dataset(
|
|
77 |
logger.info("Start loading dataset")
|
78 |
ds = _load_dataset(streaming=True, use_local_dataset=False)
|
79 |
logger.info("Dataset loaded")
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
ds_iter = iter(ds["train"])
|
|
|
84 |
|
85 |
shortcut_js = """
|
86 |
<script>
|
87 |
function shortcuts(e) {
|
88 |
-
if (e.key === "
|
89 |
document.getElementById("btn_skip").click();
|
90 |
} else if (e.key === "0") {
|
91 |
document.getElementById("btn_0").click();
|
@@ -123,7 +126,9 @@ def modify_speed(
|
|
123 |
return sr, librosa.effects.time_stretch(array, rate=speed)
|
124 |
|
125 |
|
126 |
-
def parse_item(item
|
|
|
|
|
127 |
label_id = item["cls"]
|
128 |
sampling_rate = item["audio"]["sampling_rate"]
|
129 |
array = item["audio"]["array"]
|
@@ -134,13 +139,24 @@ def parse_item(item, speed: float = 1.0) -> dict:
|
|
134 |
"text": item["txt"],
|
135 |
"label": id2rich_label[label_id],
|
136 |
"label_id": label_id,
|
|
|
137 |
}
|
138 |
|
139 |
|
140 |
-
def get_next_parsed_item(
|
|
|
141 |
logger.info("Getting next item")
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
logger.info(
|
145 |
f"Next item:\nkey={parsed['key']}\ntext={parsed['text']}\nlabel={parsed['label']}"
|
146 |
)
|
@@ -150,17 +166,18 @@ def get_next_parsed_item(speed: float = 1.0) -> dict:
|
|
150 |
md = """
|
151 |
# 説明
|
152 |
|
153 |
-
- このアプリは、ゲームのセリフを感情ラベル付けして、大規模な感情音声データセットを作成するためのものです
|
154 |
- **性的な音声が含まれるため、18歳未満の方はご利用をお控えください**
|
155 |
-
-
|
156 |
-
-
|
157 |
-
-
|
|
|
158 |
|
159 |
-
#
|
160 |
|
161 |
- `🥰 NSFW1` は女性の性的行為中の音声(喘ぎ声等)
|
162 |
-
- `🍭 NSFW2`
|
163 |
-
-
|
|
|
164 |
"""
|
165 |
|
166 |
with gr.Blocks(head=shortcut_js) as app:
|
@@ -168,16 +185,21 @@ with gr.Blocks(head=shortcut_js) as app:
|
|
168 |
with gr.Row():
|
169 |
with gr.Column():
|
170 |
btn_init = gr.Button("初期化・再読み込み")
|
171 |
-
|
172 |
minimum=0.5, maximum=5.0, step=0.1, value=1.0, label="再生速度"
|
173 |
)
|
|
|
174 |
with gr.Column(variant="panel"):
|
175 |
key = gr.Textbox(label="Key")
|
176 |
-
audio = gr.Audio(
|
|
|
|
|
|
|
|
|
177 |
text = gr.Textbox(label="Text")
|
178 |
label = gr.Textbox(label="感情ラベル")
|
179 |
label_id = gr.Textbox(visible=False)
|
180 |
-
btn_skip = gr.Button("現在の感情ラベルで適切 (
|
181 |
with gr.Column():
|
182 |
gr.Markdown("# 感情ラベルを修正する場合")
|
183 |
btn_list = [
|
@@ -187,21 +209,21 @@ with gr.Blocks(head=shortcut_js) as app:
|
|
187 |
def update_current_item(data: dict) -> dict:
|
188 |
global current_item
|
189 |
if current_item is None:
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
return {
|
194 |
key: current_item["key"],
|
195 |
audio: gr.Audio(modified_audio, autoplay=True),
|
196 |
text: current_item["text"],
|
197 |
label: current_item["label"],
|
198 |
label_id: current_item["label_id"],
|
|
|
199 |
}
|
200 |
|
201 |
def set_next_item(data: dict) -> dict:
|
202 |
global current_item
|
203 |
-
|
204 |
-
current_item = get_next_parsed_item(speed=speed_value)
|
205 |
return update_current_item(data)
|
206 |
|
207 |
def put_unmodified(data: dict) -> dict:
|
@@ -221,13 +243,15 @@ with gr.Blocks(head=shortcut_js) as app:
|
|
221 |
return set_next_item(data)
|
222 |
|
223 |
btn_init.click(
|
224 |
-
update_current_item,
|
|
|
|
|
225 |
)
|
226 |
|
227 |
btn_skip.click(
|
228 |
put_unmodified,
|
229 |
-
inputs={key, label_id,
|
230 |
-
outputs=[key, audio, text, label, label_id],
|
231 |
)
|
232 |
|
233 |
functions_list = []
|
@@ -253,8 +277,8 @@ with gr.Blocks(head=shortcut_js) as app:
|
|
253 |
for _id in range(10):
|
254 |
btn_list[_id].click(
|
255 |
functions_list[_id],
|
256 |
-
inputs={key,
|
257 |
-
outputs=[key, audio, text, label, label_id],
|
258 |
)
|
259 |
|
260 |
app.launch()
|
|
|
1 |
import json
|
2 |
import os
|
3 |
+
import random
|
4 |
import warnings
|
5 |
|
6 |
import gradio as gr
|
|
|
13 |
warnings.filterwarnings("ignore")
|
14 |
|
15 |
NUM_TAR_FILES = 115
|
16 |
+
NUM_SAMPLES = 3746131
|
17 |
HF_PATH_TO_DATASET = "litagin/Galgame_Speech_SER_16kHz"
|
18 |
|
19 |
hf_token = os.getenv("HF_TOKEN")
|
|
|
79 |
logger.info("Start loading dataset")
|
80 |
ds = _load_dataset(streaming=True, use_local_dataset=False)
|
81 |
logger.info("Dataset loaded")
|
82 |
+
seed = random.randint(0, 2**32 - 1)
|
83 |
+
logger.info(f"Seed: {seed}")
|
84 |
+
ds_iter = iter(ds["train"].shuffle(seed=seed))
|
85 |
+
# ds_iter = iter(ds["train"])
|
86 |
+
counter = 0
|
87 |
|
88 |
shortcut_js = """
|
89 |
<script>
|
90 |
function shortcuts(e) {
|
91 |
+
if (e.key === "a") {
|
92 |
document.getElementById("btn_skip").click();
|
93 |
} else if (e.key === "0") {
|
94 |
document.getElementById("btn_0").click();
|
|
|
126 |
return sr, librosa.effects.time_stretch(array, rate=speed)
|
127 |
|
128 |
|
129 |
+
def parse_item(item) -> dict:
|
130 |
+
global counter
|
131 |
+
|
132 |
label_id = item["cls"]
|
133 |
sampling_rate = item["audio"]["sampling_rate"]
|
134 |
array = item["audio"]["array"]
|
|
|
139 |
"text": item["txt"],
|
140 |
"label": id2rich_label[label_id],
|
141 |
"label_id": label_id,
|
142 |
+
"counter": counter,
|
143 |
}
|
144 |
|
145 |
|
146 |
+
def get_next_parsed_item() -> dict:
|
147 |
+
global counter, ds_iter
|
148 |
logger.info("Getting next item")
|
149 |
+
try:
|
150 |
+
next_item = next(ds_iter)
|
151 |
+
counter += 1
|
152 |
+
except StopIteration:
|
153 |
+
logger.info("StopIteration, re-initializing using new seed")
|
154 |
+
seed = random.randint(0, 2**32 - 1)
|
155 |
+
logger.info(f"New Seed: {seed}")
|
156 |
+
ds_iter = iter(ds["train"].shuffle(seed=seed))
|
157 |
+
next_item = next(ds_iter)
|
158 |
+
counter = 1
|
159 |
+
parsed = parse_item(next_item)
|
160 |
logger.info(
|
161 |
f"Next item:\nkey={parsed['key']}\ntext={parsed['text']}\nlabel={parsed['label']}"
|
162 |
)
|
|
|
166 |
md = """
|
167 |
# 説明
|
168 |
|
|
|
169 |
- **性的な音声が含まれるため、18歳未満の方はご利用をお控えください**
|
170 |
+
- このアプリは [このゲームのセリフ音声データセット](https://huggingface.co/datasets/litagin/Galgame_Speech_SER_16kHz) の感情ラベルを修正して、大規模で高品質な感情音声データセットを作成するためのものです
|
171 |
+
- 「**何を言っているか**」ではなく「**どのように言っているか**」に注目して、感情ラベルを付与してください(例: 悲しそうに「とっても楽しいです…」と言っていたら、 `😊 幸せ` ではなく `😢 悲しみ` とする)
|
172 |
+
- 既存のラベルが適切であれば、そのまま「現在の感情ラベルで適切」ボタンを押してください(ショートカットキー: `A`)
|
173 |
+
- ラベルを修正する場合は、適切なボタンを押してください(ショートカットキー: `0` 〜 `9`)
|
174 |
|
175 |
+
# ラベル補足
|
176 |
|
177 |
- `🥰 NSFW1` は女性の性的行為中の音声(喘ぎ声等)
|
178 |
+
- `🍭 NSFW2` はキスシーンでのリップ音やフェラシーンでのしゃぶる音(チュパ音)が多く含まれている音声(セリフ+チュパ音の場合も含む)(フェラシーン中のセリフだと思われる場合はこれ)
|
179 |
+
- 感情が音声からは特に読み取れない場合(普通のテンションの声で「今日はラーメンを食べます」等)は `😐 中立` を選択してください
|
180 |
+
- 複数の感情が含まれている場合は、最も多く含まれている感情を選択してください
|
181 |
"""
|
182 |
|
183 |
with gr.Blocks(head=shortcut_js) as app:
|
|
|
185 |
with gr.Row():
|
186 |
with gr.Column():
|
187 |
btn_init = gr.Button("初期化・再読み込み")
|
188 |
+
speed_slider = gr.Slider(
|
189 |
minimum=0.5, maximum=5.0, step=0.1, value=1.0, label="再生速度"
|
190 |
)
|
191 |
+
counter_info = gr.Textbox(label="進捗状況")
|
192 |
with gr.Column(variant="panel"):
|
193 |
key = gr.Textbox(label="Key")
|
194 |
+
audio = gr.Audio(
|
195 |
+
show_download_button=False,
|
196 |
+
show_share_button=False,
|
197 |
+
interactive=False,
|
198 |
+
)
|
199 |
text = gr.Textbox(label="Text")
|
200 |
label = gr.Textbox(label="感情ラベル")
|
201 |
label_id = gr.Textbox(visible=False)
|
202 |
+
btn_skip = gr.Button("現在の感情ラベルで適切 (A)", elem_id="btn_skip")
|
203 |
with gr.Column():
|
204 |
gr.Markdown("# 感情ラベルを修正する場合")
|
205 |
btn_list = [
|
|
|
209 |
def update_current_item(data: dict) -> dict:
|
210 |
global current_item
|
211 |
if current_item is None:
|
212 |
+
current_item = get_next_parsed_item()
|
213 |
+
modified_audio = modify_speed(current_item["audio"], speed=data[speed_slider])
|
214 |
+
counter_str = f"{current_item['counter']}/{NUM_SAMPLES}: {current_item['counter'] / NUM_SAMPLES * 100:.2f}%"
|
215 |
return {
|
216 |
key: current_item["key"],
|
217 |
audio: gr.Audio(modified_audio, autoplay=True),
|
218 |
text: current_item["text"],
|
219 |
label: current_item["label"],
|
220 |
label_id: current_item["label_id"],
|
221 |
+
counter_info: counter_str,
|
222 |
}
|
223 |
|
224 |
def set_next_item(data: dict) -> dict:
|
225 |
global current_item
|
226 |
+
current_item = get_next_parsed_item()
|
|
|
227 |
return update_current_item(data)
|
228 |
|
229 |
def put_unmodified(data: dict) -> dict:
|
|
|
243 |
return set_next_item(data)
|
244 |
|
245 |
btn_init.click(
|
246 |
+
update_current_item,
|
247 |
+
inputs={speed_slider},
|
248 |
+
outputs=[key, audio, text, label, label_id, counter_info],
|
249 |
)
|
250 |
|
251 |
btn_skip.click(
|
252 |
put_unmodified,
|
253 |
+
inputs={key, label_id, speed_slider},
|
254 |
+
outputs=[key, audio, text, label, label_id, counter_info],
|
255 |
)
|
256 |
|
257 |
functions_list = []
|
|
|
277 |
for _id in range(10):
|
278 |
btn_list[_id].click(
|
279 |
functions_list[_id],
|
280 |
+
inputs={key, speed_slider},
|
281 |
+
outputs=[key, audio, text, label, label_id, counter_info],
|
282 |
)
|
283 |
|
284 |
app.launch()
|