[Bugfix] Fix Higgs Audio v3 voice-clone token validation (#7065)
Signed-off-by: luozijian <luozijian0924@gmail.com>
This commit is contained in:
1 parent
66d938100b
commit
b6b992ac7b
6 files changed
+190
-37
No files matched your search
@@ -892,6 +892,81 @@ class TestFeedbackMethods:
|
||||
assert r2 == {} # Second row is all -1
|
||||
|
||||
|
||||
# ---- AC-3: Reference Audio Substitution Tests ----
|
||||
|
||||
|
||||
class TestReferenceAudioSubstitution:
|
||||
def _make_talker(self, query_start_loc):
|
||||
from vllm_omni.model_executor.models.higgs_audio_v3 import higgs_audio_v3_talker as mod
|
||||
|
||||
class FakeTalker:
|
||||
_last_step_query_start_loc = query_start_loc
|
||||
_apply_ref_audio_substitution = mod.HiggsAudioV3TalkerForConditionalGeneration._apply_ref_audio_substitution
|
||||
|
||||
@staticmethod
|
||||
def multimodal_embedding(codes):
|
||||
return codes.to(torch.float32)
|
||||
|
||||
return FakeTalker()
|
||||
|
||||
@staticmethod
|
||||
def _reference_info():
|
||||
return [
|
||||
{
|
||||
"audio_input_ids": torch.tensor([[5], [7]], dtype=torch.long),
|
||||
"audio_input_ids_mask": torch.tensor([True, True]),
|
||||
"audio_placeholder_positions": torch.tensor([1, 2]),
|
||||
}
|
||||
]
|
||||
|
||||
def test_valid_placeholder_tokens_are_replaced_from_explicit_positions(self):
|
||||
talker = self._make_talker(torch.tensor([0, 4]))
|
||||
hidden_states = torch.zeros(4, 1)
|
||||
input_ids = torch.tensor([1, 151702, 151702, 2])
|
||||
positions = torch.arange(4)
|
||||
|
||||
result = talker._apply_ref_audio_substitution(
|
||||
hidden_states,
|
||||
input_ids,
|
||||
positions,
|
||||
self._reference_info(),
|
||||
)
|
||||
|
||||
assert result[:, 0].tolist() == [0.0, 5.0, 7.0, 0.0]
|
||||
|
||||
def test_chunked_prefill_selects_code_by_absolute_prompt_position(self):
|
||||
talker = self._make_talker(torch.tensor([0, 1]))
|
||||
hidden_states = torch.zeros(1, 1)
|
||||
input_ids = torch.tensor([151702])
|
||||
positions = torch.tensor([2])
|
||||
|
||||
result = talker._apply_ref_audio_substitution(
|
||||
hidden_states,
|
||||
input_ids,
|
||||
positions,
|
||||
self._reference_info(),
|
||||
)
|
||||
|
||||
assert result[:, 0].tolist() == [7.0]
|
||||
|
||||
def test_legacy_negative_placeholder_tokens_remain_supported(self):
|
||||
talker = self._make_talker(torch.tensor([0, 4]))
|
||||
hidden_states = torch.zeros(4, 1)
|
||||
input_ids = torch.tensor([1, -100, -100, 2])
|
||||
positions = torch.arange(4)
|
||||
reference_info = self._reference_info()
|
||||
reference_info[0].pop("audio_placeholder_positions")
|
||||
|
||||
result = talker._apply_ref_audio_substitution(
|
||||
hidden_states,
|
||||
input_ids,
|
||||
positions,
|
||||
reference_info,
|
||||
)
|
||||
|
||||
assert result[:, 0].tolist() == [0.0, 5.0, 7.0, 0.0]
|
||||
|
||||
|
||||
# ---- AC-6: Audio Feedback Method Tests ----
|
||||
|
||||
|
||||
@@ -1545,6 +1620,23 @@ class TestPromptBuilder:
|
||||
assert 151703 not in ids # <|ref_audio|>
|
||||
assert 151704 not in ids # <|ref_text|>
|
||||
|
||||
def test_voice_clone_prompt_is_vocab_valid_for_engine(self):
|
||||
from vllm_omni.model_executor.models.higgs_audio_v3.higgs_audio_v3_tokenizer import (
|
||||
HiggsAudioV3TokenizerAdapter,
|
||||
)
|
||||
|
||||
adapter = HiggsAudioV3TokenizerAdapter(self._make_mock_tokenizer())
|
||||
prompt_ids = adapter.build_prompt("Hello", num_ref_tokens=2)
|
||||
|
||||
engine_prompt_ids, placeholder_positions = adapter.prepare_prompt_for_engine(prompt_ids)
|
||||
|
||||
assert min(prompt_ids) < 0
|
||||
assert min(engine_prompt_ids) >= 0
|
||||
assert placeholder_positions.tolist() == [2, 3]
|
||||
filler_ids = [engine_prompt_ids[index] for index in placeholder_positions.tolist()]
|
||||
assert filler_ids == [adapter.tts_id] * 2
|
||||
assert adapter.audio_id not in filler_ids
|
||||
|
||||
|
||||
class TestVoiceCloneReferenceCache:
|
||||
def test_audio_tokenizer_dir_env_accepts_parent_or_subdir(self, tmp_path, monkeypatch):
|
||||
|
||||
Reference in new issue
Block a user