Update modeling_minicpmo.py

#20
Files changed (2) hide show
  1. modeling_minicpmo.py +43 -36
  2. processing_minicpmo.py +1 -1
modeling_minicpmo.py CHANGED
@@ -763,37 +763,36 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
763
  audio_embs = audio_embeddings[i]
764
  bounds = audio_bounds[i]
765
 
766
- one_to_one_match = len(audio_embs) == len(bounds) and all(
767
- embs.shape[0] == int(bound[1] - bound[0])
768
- for embs, bound in zip(audio_embs, bounds)
769
- )
770
 
771
- if one_to_one_match:
772
- for embs, bound in zip(audio_embs, bounds):
773
- input_embeddings[i, bound[0] : bound[1]] = embs.to(
 
 
 
 
 
774
  device=input_embeddings.device,
775
  dtype=input_embeddings.dtype,
776
  )
777
- else:
778
- flat_audio_embs = torch.cat(audio_embs, dim=0).to(
779
- device=input_embeddings.device,
780
- dtype=input_embeddings.dtype,
781
- )
782
-
783
- total_bound_len = sum(int(bound[1] - bound[0]) for bound in bounds)
784
-
785
- if flat_audio_embs.shape[0] != total_bound_len:
786
- raise ValueError(
787
- f"Audio total length mismatch: {flat_audio_embs.shape[0]} != {total_bound_len}"
788
- )
789
-
790
- offset = 0
791
- for bound in bounds:
792
- audio_len = int(bound[1] - bound[0])
793
- input_embeddings[i, bound[0] : bound[1]] = flat_audio_embs[
794
- offset : offset + audio_len
795
- ]
796
- offset += audio_len
797
 
798
  elif self.training:
799
  for i in range(bs):
@@ -853,10 +852,12 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
853
  result_text = []
854
  for result in result_ids:
855
  result = result[result != 0]
856
- if result[0] == tokenizer.bos_id:
857
  result = result[1:]
858
- if result[-1] in terminators:
859
- result = result[:-1]
 
 
860
  result_text.append(tokenizer.decode(result))
861
  return result_text
862
 
@@ -1129,8 +1130,10 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
1129
  input_images_list = []
1130
  input_audios_list = []
1131
  audio_parts_list = []
 
1132
 
1133
  for image, msgs in zip(images_list, msgs_list):
 
1134
  if isinstance(msgs, str):
1135
  msgs = json.loads(msgs)
1136
  copy_msgs = deepcopy(msgs)
@@ -1161,7 +1164,7 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
1161
  audios.append(c)
1162
  audio_parts.append(i)
1163
  cur_msgs.append("<audio>./</audio>")
1164
- use_tts_template = True
1165
  elif isinstance(c, str):
1166
  cur_msgs.append(c)
1167
 
@@ -1175,13 +1178,18 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
1175
  copy_msgs,
1176
  tokenize=False,
1177
  add_generation_prompt=False if teacher_forcing else True,
1178
- use_tts_template=use_tts_template,
1179
  enable_thinking=enable_thinking,
1180
  )
1181
  )
1182
  input_images_list.append(images)
1183
  input_audios_list.append(audios)
1184
  audio_parts_list.append(audio_parts)
 
 
 
 
 
1185
 
1186
  if not merge_audio_from_same_content:
1187
  audio_parts_list = None
@@ -1253,9 +1261,8 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
1253
 
1254
  tts_bound = (tts_bos_idx, tts_eos_idx)
1255
 
1256
- answer = res[0]
1257
- if answer is not None:
1258
- answer = answer.split("<|tts_eos|>")[0]
1259
 
1260
  if use_tts_template and generate_audio and output_audio_path:
1261
  import soundfile as sf
@@ -1284,7 +1291,7 @@ class MiniCPMO(MiniCPMOPreTrainedModel):
1284
  traceback.print_exc()
1285
 
1286
  if return_prompt:
1287
- return answer, prompts_lists[0]
1288
  else:
1289
  return answer
1290
 
 
763
  audio_embs = audio_embeddings[i]
764
  bounds = audio_bounds[i]
765
 
766
+ one_to_one_match = len(audio_embs) == len(bounds) and all(
767
+ embs.shape[0] == int(bound[1] - bound[0])
768
+ for embs, bound in zip(audio_embs, bounds)
769
+ )
770
 
771
+ if one_to_one_match:
772
+ for embs, bound in zip(audio_embs, bounds):
773
+ input_embeddings[i, bound[0] : bound[1]] = embs.to(
774
+ device=input_embeddings.device,
775
+ dtype=input_embeddings.dtype,
776
+ )
777
+ else:
778
+ flat_audio_embs = torch.cat(audio_embs, dim=0).to(
779
  device=input_embeddings.device,
780
  dtype=input_embeddings.dtype,
781
  )
782
+
783
+ total_bound_len = sum(int(bound[1] - bound[0]) for bound in bounds)
784
+ if flat_audio_embs.shape[0] != total_bound_len:
785
+ raise ValueError(
786
+ f"Audio total length mismatch: {flat_audio_embs.shape[0]} != {total_bound_len}"
787
+ )
788
+
789
+ offset = 0
790
+ for bound in bounds:
791
+ audio_len = int(bound[1] - bound[0])
792
+ input_embeddings[i, bound[0] : bound[1]] = flat_audio_embs[
793
+ offset : offset + audio_len
794
+ ]
795
+ offset += audio_len
 
 
 
 
 
 
796
 
797
  elif self.training:
798
  for i in range(bs):
 
852
  result_text = []
853
  for result in result_ids:
854
  result = result[result != 0]
855
+ if len(result) > 0 and result[0] == tokenizer.bos_id:
856
  result = result[1:]
857
+ for idx, token_id in enumerate(result):
858
+ if token_id in terminators:
859
+ result = result[:idx]
860
+ break
861
  result_text.append(tokenizer.decode(result))
862
  return result_text
863
 
 
1130
  input_images_list = []
1131
  input_audios_list = []
1132
  audio_parts_list = []
1133
+ use_tts_template_list = []
1134
 
1135
  for image, msgs in zip(images_list, msgs_list):
1136
+ sample_use_tts_template = use_tts_template
1137
  if isinstance(msgs, str):
1138
  msgs = json.loads(msgs)
1139
  copy_msgs = deepcopy(msgs)
 
1164
  audios.append(c)
1165
  audio_parts.append(i)
1166
  cur_msgs.append("<audio>./</audio>")
1167
+ sample_use_tts_template = True
1168
  elif isinstance(c, str):
1169
  cur_msgs.append(c)
1170
 
 
1178
  copy_msgs,
1179
  tokenize=False,
1180
  add_generation_prompt=False if teacher_forcing else True,
1181
+ use_tts_template=sample_use_tts_template,
1182
  enable_thinking=enable_thinking,
1183
  )
1184
  )
1185
  input_images_list.append(images)
1186
  input_audios_list.append(audios)
1187
  audio_parts_list.append(audio_parts)
1188
+ use_tts_template_list.append(sample_use_tts_template)
1189
+
1190
+ # Preserve the original downstream behavior for optional audio generation,
1191
+ # while keeping prompt template selection local to each batch sample.
1192
+ use_tts_template = any(use_tts_template_list)
1193
 
1194
  if not merge_audio_from_same_content:
1195
  audio_parts_list = None
 
1261
 
1262
  tts_bound = (tts_bos_idx, tts_eos_idx)
1263
 
1264
+ answers = [answer.split("<|tts_eos|>")[0] if answer is not None else None for answer in res]
1265
+ answer = answers if batched else answers[0]
 
1266
 
1267
  if use_tts_template and generate_audio and output_audio_path:
1268
  import soundfile as sf
 
1291
  traceback.print_exc()
1292
 
1293
  if return_prompt:
1294
+ return answer, prompts_lists if batched else prompts_lists[0]
1295
  else:
1296
  return answer
1297
 
processing_minicpmo.py CHANGED
@@ -1471,7 +1471,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]
 
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(torch.empty(0, dtype=torch.long))
1475
 
1476
  if audio_features_all:
1477
  audio_features = [i.permute(1, 0) for i in audio_features_all]