litagin commited on
Commit
0cd70b9
·
1 Parent(s): 344cf8a
Files changed (1) hide show
  1. app.py +53 -29
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
- # seed = random.randint(0, 2**32 - 1)
81
- # logger.info(f"Seed: {seed}")
82
- # ds_iter = iter(ds["train"].shuffle(seed=seed))
83
- ds_iter = iter(ds["train"])
 
84
 
85
  shortcut_js = """
86
  <script>
87
  function shortcuts(e) {
88
- if (e.key === "Enter") {
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, speed: float = 1.0) -> dict:
 
 
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(speed: float = 1.0) -> dict:
 
141
  logger.info("Getting next item")
142
- next_item = next(ds_iter)
143
- parsed = parse_item(next_item, speed=speed)
 
 
 
 
 
 
 
 
 
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
- speed = gr.Slider(
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("現在の感情ラベルで適切 (Enter)", elem_id="btn_skip")
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
- speed_value = data[speed]
191
- current_item = get_next_parsed_item(speed=speed_value)
192
- modified_audio = modify_speed(current_item["audio"], speed=data[speed])
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
- speed_value = data[speed]
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, inputs={speed}, outputs=[key, audio, text, label, label_id]
 
 
225
  )
226
 
227
  btn_skip.click(
228
  put_unmodified,
229
- inputs={key, label_id, speed},
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, speed},
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()