Fix audio placeholder length mismatch for merged audio inputs

#19
Files changed (1) hide show
  1. processing_minicpmo.py +49 -20
processing_minicpmo.py CHANGED
@@ -1039,16 +1039,16 @@ class MiniCPMOProcessor(ProcessorMixin):
1039
  Returns:
1040
  Audio placeholder string
1041
  """
1042
- pool_step = self.pool_step
1043
  feature_lens = math.ceil(audio_lens / self.audio_processor.hop_length)
1044
-
1045
  feature_lens = (feature_lens - 1) // 2 + 1
1046
- output_lens = (feature_lens - pool_step) // pool_step + 1
 
1047
 
 
1048
  if chunk_input:
1049
  fbank_feat_in_chunk = int(chunk_length * 100)
1050
  cnn_feat_in_chunk = (fbank_feat_in_chunk - 1) // 2 + 1
1051
- audio_embeds_in_chunk = (cnn_feat_in_chunk - pool_step) // pool_step + 1
1052
  num_audio_chunks = (output_lens + audio_embeds_in_chunk - 1) // audio_embeds_in_chunk
1053
 
1054
  place_holders = ""
@@ -1063,6 +1063,27 @@ class MiniCPMOProcessor(ProcessorMixin):
1063
 
1064
  return audio_placeholder
1065
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1066
  def _init_streaming_processor(
1067
  self,
1068
  chunk_ms: int = 100,
@@ -1382,7 +1403,7 @@ class MiniCPMOProcessor(ProcessorMixin):
1382
 
1383
  if isinstance(audios, np.ndarray):
1384
  audios_list = [[audios]]
1385
- elif isinstance(audios[0], np.ndarray):
1386
  audios_list = [audios]
1387
  else:
1388
  audios_list = audios
@@ -1393,37 +1414,45 @@ class MiniCPMOProcessor(ProcessorMixin):
1393
  assert len(parts) == len(audios)
1394
 
1395
  audio_feature_lens_list = []
1396
- audio_ph_list = []
1397
  audio_features_all = []
1398
 
1399
- # audio placeholder not dependent on audio_parts
1400
- for audios in audios_list:
1401
- if audios:
1402
- audio_ph_list.append(
1403
- [
1404
- self.get_audio_placeholder(len(a), chunk_input=stream_input, chunk_length=chunk_length)
1405
- for a in audios
1406
- ]
1407
- )
1408
- else:
1409
- audio_ph_list.append([])
1410
-
1411
  for idx, audios in enumerate(audios_list):
1412
  if audio_parts is not None:
1413
- # same audio part merge
1414
  audio_part = audio_parts[idx]
1415
  merge_audio = []
1416
  cur_audio = []
 
1417
  for aid, (part, audio) in enumerate(zip(audio_part, audios)):
1418
  if aid == 0 or audio_part[aid] == audio_part[aid - 1]:
1419
  cur_audio.append(audio)
1420
  else:
1421
  merge_audio.append(np.hstack(cur_audio))
 
 
 
 
 
 
 
1422
  cur_audio = [audio]
1423
  if cur_audio:
1424
  merge_audio.append(np.hstack(cur_audio))
 
 
 
 
 
 
 
1425
  else:
1426
  merge_audio = audios
 
 
 
 
 
 
1427
 
1428
  # If the audio exceeds 30 seconds, split it into chunks every 30 seconds.
1429
  final_merge_audio = []
@@ -1471,7 +1500,7 @@ class MiniCPMOProcessor(ProcessorMixin):
1471
  audio_feature_lens = torch.hstack(audio_feature_lens)
1472
  audio_feature_lens_list.append(audio_feature_lens)
1473
  else:
1474
- audio_feature_lens_list.append([])
1475
 
1476
  if audio_features_all:
1477
  audio_features = [i.permute(1, 0) for i in audio_features_all]
 
1039
  Returns:
1040
  Audio placeholder string
1041
  """
 
1042
  feature_lens = math.ceil(audio_lens / self.audio_processor.hop_length)
 
1043
  feature_lens = (feature_lens - 1) // 2 + 1
1044
+ output_lens = (feature_lens - self.pool_step) // self.pool_step + 1
1045
+ return self._get_audio_placeholder_by_output_lens(output_lens, chunk_input, chunk_length)
1046
 
1047
+ def _get_audio_placeholder_by_output_lens(self, output_lens: int, chunk_input: bool = True, chunk_length: int = 1):
1048
  if chunk_input:
1049
  fbank_feat_in_chunk = int(chunk_length * 100)
1050
  cnn_feat_in_chunk = (fbank_feat_in_chunk - 1) // 2 + 1
1051
+ audio_embeds_in_chunk = (cnn_feat_in_chunk - self.pool_step) // self.pool_step + 1
1052
  num_audio_chunks = (output_lens + audio_embeds_in_chunk - 1) // audio_embeds_in_chunk
1053
 
1054
  place_holders = ""
 
1063
 
1064
  return audio_placeholder
1065
 
1066
+ def _get_merged_audio_placeholders(self, audios, chunk_input: bool = True, chunk_length: int = 1):
1067
+ audio_placeholders = []
1068
+ prev_output_lens = 0
1069
+ total_audio_lens = 0
1070
+ for audio in audios:
1071
+ total_audio_lens += len(audio)
1072
+ output_lens = self.get_audio_placeholder(
1073
+ total_audio_lens,
1074
+ chunk_input=chunk_input,
1075
+ chunk_length=chunk_length,
1076
+ ).count("<unk>")
1077
+ audio_placeholders.append(
1078
+ self._get_audio_placeholder_by_output_lens(
1079
+ output_lens - prev_output_lens,
1080
+ chunk_input=chunk_input,
1081
+ chunk_length=chunk_length,
1082
+ )
1083
+ )
1084
+ prev_output_lens = output_lens
1085
+ return audio_placeholders
1086
+
1087
  def _init_streaming_processor(
1088
  self,
1089
  chunk_ms: int = 100,
 
1403
 
1404
  if isinstance(audios, np.ndarray):
1405
  audios_list = [[audios]]
1406
+ elif len(audios) > 0 and isinstance(audios[0], np.ndarray):
1407
  audios_list = [audios]
1408
  else:
1409
  audios_list = audios
 
1414
  assert len(parts) == len(audios)
1415
 
1416
  audio_feature_lens_list = []
1417
+ audio_ph_list = [[] for _ in audios_list]
1418
  audio_features_all = []
1419
 
 
 
 
 
 
 
 
 
 
 
 
 
1420
  for idx, audios in enumerate(audios_list):
1421
  if audio_parts is not None:
 
1422
  audio_part = audio_parts[idx]
1423
  merge_audio = []
1424
  cur_audio = []
1425
+ audio_phs = []
1426
  for aid, (part, audio) in enumerate(zip(audio_part, audios)):
1427
  if aid == 0 or audio_part[aid] == audio_part[aid - 1]:
1428
  cur_audio.append(audio)
1429
  else:
1430
  merge_audio.append(np.hstack(cur_audio))
1431
+ audio_phs.extend(
1432
+ self._get_merged_audio_placeholders(
1433
+ cur_audio,
1434
+ chunk_input=stream_input,
1435
+ chunk_length=chunk_length,
1436
+ )
1437
+ )
1438
  cur_audio = [audio]
1439
  if cur_audio:
1440
  merge_audio.append(np.hstack(cur_audio))
1441
+ audio_phs.extend(
1442
+ self._get_merged_audio_placeholders(
1443
+ cur_audio,
1444
+ chunk_input=stream_input,
1445
+ chunk_length=chunk_length,
1446
+ )
1447
+ )
1448
  else:
1449
  merge_audio = audios
1450
+ audio_phs = [
1451
+ self.get_audio_placeholder(len(a), chunk_input=stream_input, chunk_length=chunk_length)
1452
+ for a in audios
1453
+ ]
1454
+
1455
+ audio_ph_list[idx] = audio_phs
1456
 
1457
  # If the audio exceeds 30 seconds, split it into chunks every 30 seconds.
1458
  final_merge_audio = []
 
1500
  audio_feature_lens = torch.hstack(audio_feature_lens)
1501
  audio_feature_lens_list.append(audio_feature_lens)
1502
  else:
1503
+ audio_feature_lens_list.append(torch.tensor([], dtype=torch.long))
1504
 
1505
  if audio_features_all:
1506
  audio_features = [i.permute(1, 0) for i in audio_features_all]