abtonmoy commited on
Commit
e6d91bc
·
verified ·
1 Parent(s): 27e1dd7

Remote code: batched embed_text_batch / embed_audio_batch entry points

Browse files
Files changed (1) hide show
  1. modeling_fusion_embedding.py +68 -0
modeling_fusion_embedding.py CHANGED
@@ -439,6 +439,74 @@ class FusionEmbeddingModel(PreTrainedModel):
439
  pooled = last_token_pool(h, inputs["attention_mask"])
440
  return self._finish(pooled, dim)
441
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  # ------------------------------------------------------------- read-out
443
  @staticmethod
444
  def center(embs: torch.Tensor) -> torch.Tensor:
 
439
  pooled = last_token_pool(h, inputs["attention_mask"])
440
  return self._finish(pooled, dim)
441
 
442
+ # ------------------------------------------------------------- batched
443
+ @torch.no_grad()
444
+ def embed_text_batch(self, texts, instruction: str = DEFAULT_QUERY_INSTRUCTION,
445
+ dim: Optional[int] = None,
446
+ max_tokens: Optional[int] = None) -> torch.Tensor:
447
+ """Batch text embedding [B, dim] (right-padded, mask-aware last-token pooling)."""
448
+ self._ensure_backbones()
449
+ if self._rt["gate"].active:
450
+ raise RuntimeError("adapter gate is open during a text encode — "
451
+ "non-audio inputs must run with the gate closed")
452
+ cfg, tok = self.config, self._rt["tok"]
453
+ max_tokens = max_tokens or cfg.max_text_tokens
454
+ seqs = [tok.encode(_chat(instruction, t), add_special_tokens=False)[:max_tokens]
455
+ for t in texts]
456
+ L = max(len(s) for s in seqs)
457
+ ids = torch.full((len(seqs), L), cfg.pad_id, dtype=torch.long, device=self._device)
458
+ mask = torch.zeros(len(seqs), L, dtype=torch.long, device=self._device)
459
+ for b, s in enumerate(seqs):
460
+ ids[b, : len(s)] = torch.tensor(s, device=self._device)
461
+ mask[b, : len(s)] = 1
462
+ full = self._rt["full"]
463
+ out = full.language_model(inputs_embeds=full.get_input_embeddings()(ids),
464
+ attention_mask=mask)
465
+ hidden = out.last_hidden_state if hasattr(out, "last_hidden_state") else out[0]
466
+ pooled = self.text_whitening(last_token_pool(hidden, mask))
467
+ return mrl_truncate_normalize(pooled.float(), dim or cfg.mrl_default).cpu()
468
+
469
+ @torch.no_grad()
470
+ def embed_audio_batch(self, wavs, sr: int, dim: Optional[int] = None) -> torch.Tensor:
471
+ """Batch audio embedding [B, dim] from raw waveform arrays at a common rate."""
472
+ import librosa
473
+ import numpy as np
474
+
475
+ self._ensure_backbones()
476
+ cfg, fe_audio = self.config, self._rt["fe_audio"]
477
+ target_sr = fe_audio.sampling_rate
478
+ prepped = []
479
+ for wav in wavs:
480
+ wav = np.asarray(wav, dtype=np.float32)
481
+ if wav.ndim > 1:
482
+ wav = wav.mean(axis=-1)
483
+ if sr != target_sr:
484
+ wav = librosa.resample(wav, orig_sr=sr, target_sr=target_sr)
485
+ prepped.append(wav)
486
+ feats = fe_audio(prepped, sampling_rate=target_sr, return_tensors="pt",
487
+ return_attention_mask=True, padding="max_length", truncation=True)
488
+ mel, am = feats["input_features"], feats.get("attention_mask")
489
+ if am is not None:
490
+ tmax = int(am.sum(dim=1).max().item())
491
+ mel, am = mel[:, :, :tmax], am[:, :tmax]
492
+ fmask = (am.bool() if am is not None
493
+ else torch.ones(mel.shape[0], mel.shape[2], dtype=torch.bool))
494
+ frames, frame_mask = self._rt["tower"](mel.to(self._device),
495
+ fmask.to(self._device))
496
+ audio_tok = self.resampler(frames, frame_mask)
497
+ ids = torch.tensor([[cfg.audio_pad_id] * cfg.n_query + [cfg.eos_id]] * mel.shape[0],
498
+ device=self._device)
499
+ attention_mask = torch.ones_like(ids)
500
+ full = self._rt["full"]
501
+ embeds = full.get_input_embeddings()(ids).clone()
502
+ embeds[ids == cfg.audio_pad_id] = (
503
+ audio_tok.reshape(-1, audio_tok.size(-1)).to(embeds.dtype))
504
+ with self._rt["gate"]:
505
+ out = full.language_model(inputs_embeds=embeds, attention_mask=attention_mask)
506
+ hidden = out.last_hidden_state if hasattr(out, "last_hidden_state") else out[0]
507
+ pooled = last_token_pool(hidden, attention_mask)
508
+ return mrl_truncate_normalize(pooled.float(), dim or cfg.mrl_default).cpu()
509
+
510
  # ------------------------------------------------------------- read-out
511
  @staticmethod
512
  def center(embs: torch.Tensor) -> torch.Tensor: