Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95934535f3 |
No files matched your search
@@ -171,6 +171,12 @@ def _make_runner(req_ids=("r1", "r2"), hidden_size=4):
|
|||||||
return runner
|
return runner
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_talker_seed(runner, *, accepts_generators=False):
|
||||||
|
runner.model.talker_mtp_seed_extra_arg = "tts_local_seed"
|
||||||
|
if accepts_generators:
|
||||||
|
runner.model.talker_mtp_accepts_generators = True
|
||||||
|
|
||||||
|
|
||||||
def _make_runner_for_mimo(req_id="r_mimo"):
|
def _make_runner_for_mimo(req_id="r_mimo"):
|
||||||
"""Create a minimal runner with MiMoAudio-like model and request state."""
|
"""Create a minimal runner with MiMoAudio-like model and request state."""
|
||||||
runner = object.__new__(OmniGPUModelRunner)
|
runner = object.__new__(OmniGPUModelRunner)
|
||||||
@@ -255,6 +261,7 @@ def test_talker_mtp_forward_ignores_default_sampling_seed_without_request_marker
|
|||||||
runner = _make_runner(req_ids=("r1",), hidden_size=4)
|
runner = _make_runner(req_ids=("r1",), hidden_size=4)
|
||||||
runner.requests["r1"].sampling_params = SimpleNamespace(seed=42)
|
runner.requests["r1"].sampling_params = SimpleNamespace(seed=42)
|
||||||
runner.talker_mtp = CaptureTalkerMTP()
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
_enable_talker_seed(runner)
|
||||||
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
@@ -269,6 +276,34 @@ def test_talker_mtp_forward_ignores_default_sampling_seed_without_request_marker
|
|||||||
assert runner.talker_mtp.calls[0]["generator"] is None
|
assert runner.talker_mtp.calls[0]["generator"] is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_talker_mtp_forward_ignores_tts_local_seed_without_model_seed_key(monkeypatch):
|
||||||
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
|
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
||||||
|
|
||||||
|
runner = _make_runner(req_ids=("r1", "r2"), hidden_size=4)
|
||||||
|
runner.requests["r1"].sampling_params = SimpleNamespace(
|
||||||
|
seed=42,
|
||||||
|
extra_args={"tts_local_seed": 42},
|
||||||
|
)
|
||||||
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
runner.model.talker_mtp_accepts_generators = True
|
||||||
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
|
batch_desc = SimpleNamespace(num_tokens=int(num_tokens))
|
||||||
|
return (False, batch_desc, None, None, None)
|
||||||
|
|
||||||
|
monkeypatch.setattr(runner, "_determine_batch_execution_and_padding", fake_determine.__get__(runner, type(runner)))
|
||||||
|
|
||||||
|
inputs_embeds = torch.zeros((6, 4), dtype=torch.float32)
|
||||||
|
OmniGPUModelRunner._talker_mtp_forward(runner, ["r1", "r2"], inputs_embeds)
|
||||||
|
|
||||||
|
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [2]
|
||||||
|
assert runner.talker_mtp.calls[0]["generator"] is None
|
||||||
|
assert runner.talker_mtp.calls[0]["generators"] is None
|
||||||
|
|
||||||
|
|
||||||
def test_talker_mtp_forward_passes_qwen3_tts_subtalker_sampling_params_to_talker(monkeypatch):
|
def test_talker_mtp_forward_passes_qwen3_tts_subtalker_sampling_params_to_talker(monkeypatch):
|
||||||
import vllm_omni.worker.gpu_model_runner as mod
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
@@ -280,6 +315,7 @@ def test_talker_mtp_forward_passes_qwen3_tts_subtalker_sampling_params_to_talker
|
|||||||
extra_args={"tts_local_seed": 42},
|
extra_args={"tts_local_seed": 42},
|
||||||
)
|
)
|
||||||
runner.talker_mtp = CaptureTalkerMTP()
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
_enable_talker_seed(runner)
|
||||||
runner.vllm_config = SimpleNamespace(
|
runner.vllm_config = SimpleNamespace(
|
||||||
model_config=SimpleNamespace(
|
model_config=SimpleNamespace(
|
||||||
subtalker_sampling_params={
|
subtalker_sampling_params={
|
||||||
@@ -314,7 +350,7 @@ def test_talker_mtp_forward_passes_qwen3_tts_subtalker_sampling_params_to_talker
|
|||||||
assert runner.talker_mtp.calls[0]["generator"] is not None
|
assert runner.talker_mtp.calls[0]["generator"] is not None
|
||||||
|
|
||||||
|
|
||||||
def test_talker_mtp_forward_keeps_explicit_seeded_requests_scalar(monkeypatch):
|
def test_talker_mtp_forward_keeps_unmarked_models_scalar_for_explicit_seed(monkeypatch):
|
||||||
import vllm_omni.worker.gpu_model_runner as mod
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
||||||
@@ -329,6 +365,7 @@ def test_talker_mtp_forward_keeps_explicit_seeded_requests_scalar(monkeypatch):
|
|||||||
extra_args={"tts_local_seed": 22},
|
extra_args={"tts_local_seed": 22},
|
||||||
)
|
)
|
||||||
runner.talker_mtp = CaptureTalkerMTP()
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
_enable_talker_seed(runner)
|
||||||
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
@@ -348,13 +385,13 @@ def test_talker_mtp_forward_keeps_explicit_seeded_requests_scalar(monkeypatch):
|
|||||||
|
|
||||||
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [1, 1]
|
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [1, 1]
|
||||||
assert all(call["generator"] is not None for call in runner.talker_mtp.calls)
|
assert all(call["generator"] is not None for call in runner.talker_mtp.calls)
|
||||||
|
assert all(call["generators"] is None for call in runner.talker_mtp.calls)
|
||||||
assert runner.talker_mtp.calls[0]["generator"] is not runner.talker_mtp.calls[1]["generator"]
|
assert runner.talker_mtp.calls[0]["generator"] is not runner.talker_mtp.calls[1]["generator"]
|
||||||
assert torch.equal(runner.talker_mtp_input_ids.gpu, saved_input_ids)
|
assert torch.equal(runner.talker_mtp_input_ids.gpu, saved_input_ids)
|
||||||
assert torch.equal(runner.talker_mtp_inputs_embeds.gpu, saved_embeds)
|
assert torch.equal(runner.talker_mtp_inputs_embeds.gpu, saved_embeds)
|
||||||
|
|
||||||
|
|
||||||
def test_talker_mtp_forward_batches_seeded_requests_for_opted_in_models(monkeypatch):
|
def test_talker_mtp_forward_keeps_explicit_seeded_requests_batched(monkeypatch):
|
||||||
"""Models with talker_mtp_accepts_per_row_generators get one batched call (#4883)."""
|
|
||||||
import vllm_omni.worker.gpu_model_runner as mod
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
||||||
@@ -369,10 +406,7 @@ def test_talker_mtp_forward_batches_seeded_requests_for_opted_in_models(monkeypa
|
|||||||
extra_args={"tts_local_seed": 22},
|
extra_args={"tts_local_seed": 22},
|
||||||
)
|
)
|
||||||
runner.talker_mtp = CaptureTalkerMTP()
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
runner.model = SimpleNamespace(
|
_enable_talker_seed(runner, accepts_generators=True)
|
||||||
talker_mtp_output_key=("codes", "audio"),
|
|
||||||
talker_mtp_accepts_per_row_generators=True,
|
|
||||||
)
|
|
||||||
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
@@ -386,8 +420,9 @@ def test_talker_mtp_forward_batches_seeded_requests_for_opted_in_models(monkeypa
|
|||||||
|
|
||||||
# One batched call with distinct per-row generators, not two scalar calls.
|
# One batched call with distinct per-row generators, not two scalar calls.
|
||||||
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [2]
|
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [2]
|
||||||
row_generators = runner.talker_mtp.calls[0]["generators"]
|
|
||||||
assert runner.talker_mtp.calls[0]["generator"] is None
|
assert runner.talker_mtp.calls[0]["generator"] is None
|
||||||
|
row_generators = runner.talker_mtp.calls[0]["generators"]
|
||||||
|
assert row_generators is not None
|
||||||
assert len(row_generators) == 2
|
assert len(row_generators) == 2
|
||||||
assert all(generator is not None for generator in row_generators)
|
assert all(generator is not None for generator in row_generators)
|
||||||
assert row_generators[0] is not row_generators[1]
|
assert row_generators[0] is not row_generators[1]
|
||||||
@@ -404,6 +439,62 @@ def test_talker_mtp_forward_batches_seeded_requests_for_opted_in_models(monkeypa
|
|||||||
assert runner.talker_mtp.calls[2]["generator"] is row_generators[0]
|
assert runner.talker_mtp.calls[2]["generator"] is row_generators[0]
|
||||||
|
|
||||||
|
|
||||||
|
def test_talker_mtp_forward_batches_mixed_explicit_seed_requests(monkeypatch):
|
||||||
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
|
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
||||||
|
|
||||||
|
runner = _make_runner(req_ids=("seeded", "unseeded"), hidden_size=4)
|
||||||
|
runner.requests["seeded"].sampling_params = SimpleNamespace(
|
||||||
|
seed=11,
|
||||||
|
extra_args={"tts_local_seed": 11},
|
||||||
|
)
|
||||||
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
_enable_talker_seed(runner, accepts_generators=True)
|
||||||
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
|
batch_desc = SimpleNamespace(num_tokens=int(num_tokens))
|
||||||
|
return (False, batch_desc, None, None, None)
|
||||||
|
|
||||||
|
monkeypatch.setattr(runner, "_determine_batch_execution_and_padding", fake_determine.__get__(runner, type(runner)))
|
||||||
|
|
||||||
|
inputs_embeds = torch.zeros((6, 4), dtype=torch.float32)
|
||||||
|
OmniGPUModelRunner._talker_mtp_forward(runner, ["seeded", "unseeded"], inputs_embeds)
|
||||||
|
|
||||||
|
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [2]
|
||||||
|
assert runner.talker_mtp.calls[0]["generator"] is None
|
||||||
|
generators = runner.talker_mtp.calls[0]["generators"]
|
||||||
|
assert generators is not None
|
||||||
|
assert len(generators) == 2
|
||||||
|
assert generators[0] is not None
|
||||||
|
assert generators[1] is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_talker_mtp_forward_does_not_pass_generators_without_explicit_seed(monkeypatch):
|
||||||
|
import vllm_omni.worker.gpu_model_runner as mod
|
||||||
|
|
||||||
|
monkeypatch.setattr(mod.current_omni_platform, "set_forward_context", _noop_forward_context)
|
||||||
|
|
||||||
|
runner = _make_runner(req_ids=("r1", "r2"), hidden_size=4)
|
||||||
|
runner.talker_mtp = CaptureTalkerMTP()
|
||||||
|
_enable_talker_seed(runner, accepts_generators=True)
|
||||||
|
runner.vllm_config = SimpleNamespace(model_config=SimpleNamespace(subtalker_sampling_params={}))
|
||||||
|
|
||||||
|
def fake_determine(self, num_tokens, num_reqs, num_scheduled_tokens_np, max_num_scheduled_tokens, use_cascade_attn):
|
||||||
|
batch_desc = SimpleNamespace(num_tokens=int(num_tokens))
|
||||||
|
return (False, batch_desc, None, None, None)
|
||||||
|
|
||||||
|
monkeypatch.setattr(runner, "_determine_batch_execution_and_padding", fake_determine.__get__(runner, type(runner)))
|
||||||
|
|
||||||
|
inputs_embeds = torch.zeros((6, 4), dtype=torch.float32)
|
||||||
|
OmniGPUModelRunner._talker_mtp_forward(runner, ["r1", "r2"], inputs_embeds)
|
||||||
|
|
||||||
|
assert [call["batch_size"] for call in runner.talker_mtp.calls] == [2]
|
||||||
|
assert runner.talker_mtp.calls[0]["generator"] is None
|
||||||
|
assert runner.talker_mtp.calls[0]["generators"] is None
|
||||||
|
|
||||||
|
|
||||||
def test_update_intermediate_buffer_writes_to_buffer_and_setattr(monkeypatch):
|
def test_update_intermediate_buffer_writes_to_buffer_and_setattr(monkeypatch):
|
||||||
"""Validate that _update_intermediate_buffer writes to model_intermediate_buffer
|
"""Validate that _update_intermediate_buffer writes to model_intermediate_buffer
|
||||||
(forward path) and mirrors to additional_information_cpu setattr (backward compat)."""
|
(forward path) and mirrors to additional_information_cpu setattr (backward compat)."""
|
||||||
|
|||||||
@@ -266,6 +266,9 @@ class Qwen3TTSTalkerForConditionalGeneration(nn.Module):
|
|||||||
"""vLLM-AR talker: step-wise layer-0 codec decoding.
|
"""vLLM-AR talker: step-wise layer-0 codec decoding.
|
||||||
Predicts residual codebooks (1..Q-1) into `audio_codes` and streams text via `tailing_text_hidden`."""
|
Predicts residual codebooks (1..Q-1) into `audio_codes` and streams text via `tailing_text_hidden`."""
|
||||||
|
|
||||||
|
talker_mtp_accepts_generators = True
|
||||||
|
talker_mtp_seed_extra_arg = "tts_local_seed"
|
||||||
|
|
||||||
hf_to_vllm_mapper = WeightsMapper(
|
hf_to_vllm_mapper = WeightsMapper(
|
||||||
orig_to_new_prefix={
|
orig_to_new_prefix={
|
||||||
# Talker backbone (Qwen3 decoder-only).
|
# Talker backbone (Qwen3 decoder-only).
|
||||||
@@ -318,13 +321,6 @@ class Qwen3TTSTalkerForConditionalGeneration(nn.Module):
|
|||||||
# OmniGPUModelRunner will store talker_mtp output under this key in
|
# OmniGPUModelRunner will store talker_mtp output under this key in
|
||||||
# per-request additional_information.
|
# per-request additional_information.
|
||||||
self.talker_mtp_output_key = ("codes", "audio")
|
self.talker_mtp_output_key = ("codes", "audio")
|
||||||
# talker_mtp samples with per-row generators, so explicitly-seeded
|
|
||||||
# requests stay batched instead of one scalar forward per row (#4883).
|
|
||||||
# Only valid while talker_mtp receives the unpadded active batch (this
|
|
||||||
# talker is not graph-wrapped); a padded batch would need the runner to
|
|
||||||
# pad the generators list as well.
|
|
||||||
self.talker_mtp_accepts_per_row_generators = True
|
|
||||||
|
|
||||||
self.model = Qwen3Model(vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model"))
|
self.model = Qwen3Model(vllm_config=vllm_config, prefix=maybe_prefix(prefix, "model"))
|
||||||
|
|
||||||
if get_pp_group().is_last_rank:
|
if get_pp_group().is_last_rank:
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class OmniGPUModelRunner(GPUModelRunner):
|
|||||||
self.omni_prefix_cache = None
|
self.omni_prefix_cache = None
|
||||||
self._sampled_token_ids_cpu_override = None
|
self._sampled_token_ids_cpu_override = None
|
||||||
self._omni_query_start_loc_model_kwarg = False
|
self._omni_query_start_loc_model_kwarg = False
|
||||||
|
self._talker_mtp_generators: dict[str, torch.Generator] = {}
|
||||||
|
|
||||||
def _to_list(self, sampled_token_ids: torch.Tensor) -> list[list[int]]:
|
def _to_list(self, sampled_token_ids: torch.Tensor) -> list[list[int]]:
|
||||||
override_fn = self._sampled_token_ids_cpu_override
|
override_fn = self._sampled_token_ids_cpu_override
|
||||||
@@ -1785,6 +1786,84 @@ class OmniGPUModelRunner(GPUModelRunner):
|
|||||||
ec_connector_output,
|
ec_connector_output,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _explicit_talker_seed(self, req_id: str) -> int | None:
|
||||||
|
seed_extra_arg = getattr(self.model, "talker_mtp_seed_extra_arg", None)
|
||||||
|
if not seed_extra_arg:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sampling_params = getattr(self.requests[req_id], "sampling_params", None)
|
||||||
|
extra_args = getattr(sampling_params, "extra_args", None) if sampling_params is not None else None
|
||||||
|
if not isinstance(extra_args, dict):
|
||||||
|
return None
|
||||||
|
|
||||||
|
seed = extra_args.get(seed_extra_arg)
|
||||||
|
return int(seed) if seed is not None else None
|
||||||
|
|
||||||
|
def _resolve_talker_mtp_generators(
|
||||||
|
self,
|
||||||
|
decode_req_ids: list[str],
|
||||||
|
device: torch.device,
|
||||||
|
) -> list[torch.Generator | None] | None:
|
||||||
|
"""Resolve per-row generators aligned to ``decode_req_ids``.
|
||||||
|
|
||||||
|
``row_generators[i]`` belongs to the batched input row for
|
||||||
|
``decode_req_ids[i]``. Explicitly seeded rows use cached per-request
|
||||||
|
generators, while unseeded rows stay as ``None`` to keep global RNG
|
||||||
|
semantics. Return ``None`` when the whole batch is unseeded so callers
|
||||||
|
can use the normal batched path without sampling kwargs.
|
||||||
|
"""
|
||||||
|
generator_cache = getattr(self, "_talker_mtp_generators", None)
|
||||||
|
if generator_cache is None:
|
||||||
|
generator_cache = {}
|
||||||
|
self._talker_mtp_generators = generator_cache
|
||||||
|
|
||||||
|
row_generators: list[torch.Generator | None] = []
|
||||||
|
any_seeded = False
|
||||||
|
for req_id in decode_req_ids:
|
||||||
|
seed = self._explicit_talker_seed(req_id)
|
||||||
|
if seed is None:
|
||||||
|
row_generators.append(None)
|
||||||
|
continue
|
||||||
|
|
||||||
|
generator = generator_cache.get(req_id)
|
||||||
|
if generator is None or generator.device != device:
|
||||||
|
generator = torch.Generator(device=device)
|
||||||
|
generator.manual_seed(seed)
|
||||||
|
generator_cache[req_id] = generator
|
||||||
|
row_generators.append(generator)
|
||||||
|
any_seeded = True
|
||||||
|
|
||||||
|
for stale_id in [rid for rid in generator_cache if rid not in self.requests]:
|
||||||
|
del generator_cache[stale_id]
|
||||||
|
|
||||||
|
return row_generators if any_seeded else None
|
||||||
|
|
||||||
|
def _talker_mtp_forward_row_by_row(
|
||||||
|
self,
|
||||||
|
decode_req_ids: list[str],
|
||||||
|
inputs_embeds: torch.Tensor,
|
||||||
|
start_offsets: list[int] | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""Seeded fallback for models without batched per-row generators."""
|
||||||
|
decode_batch_size = len(decode_req_ids)
|
||||||
|
saved_input_ids = self.talker_mtp_input_ids.gpu[:decode_batch_size].clone()
|
||||||
|
saved_embeds = self.talker_mtp_inputs_embeds.gpu[:decode_batch_size].clone()
|
||||||
|
saved_hidden = self.last_talker_hidden.gpu[:decode_batch_size].clone()
|
||||||
|
saved_text = self.text_step.gpu[:decode_batch_size].clone()
|
||||||
|
try:
|
||||||
|
for row, req_id in enumerate(decode_req_ids):
|
||||||
|
self.talker_mtp_input_ids.gpu[:1].copy_(saved_input_ids[row : row + 1])
|
||||||
|
self.talker_mtp_inputs_embeds.gpu[:1].copy_(saved_embeds[row : row + 1])
|
||||||
|
self.last_talker_hidden.gpu[:1].copy_(saved_hidden[row : row + 1])
|
||||||
|
self.text_step.gpu[:1].copy_(saved_text[row : row + 1])
|
||||||
|
row_offsets = None if start_offsets is None else [start_offsets[row]]
|
||||||
|
self._talker_mtp_forward([req_id], inputs_embeds, row_offsets)
|
||||||
|
finally:
|
||||||
|
self.talker_mtp_input_ids.gpu[:decode_batch_size].copy_(saved_input_ids)
|
||||||
|
self.talker_mtp_inputs_embeds.gpu[:decode_batch_size].copy_(saved_embeds)
|
||||||
|
self.last_talker_hidden.gpu[:decode_batch_size].copy_(saved_hidden)
|
||||||
|
self.text_step.gpu[:decode_batch_size].copy_(saved_text)
|
||||||
|
|
||||||
def _talker_mtp_forward(
|
def _talker_mtp_forward(
|
||||||
self,
|
self,
|
||||||
decode_req_ids: list[str],
|
decode_req_ids: list[str],
|
||||||
@@ -1818,62 +1897,22 @@ class OmniGPUModelRunner(GPUModelRunner):
|
|||||||
if not isinstance(subtalker_params, dict):
|
if not isinstance(subtalker_params, dict):
|
||||||
subtalker_params = {}
|
subtalker_params = {}
|
||||||
|
|
||||||
def _explicit_talker_seed(req_id: str) -> int | None:
|
row_generators = self._resolve_talker_mtp_generators(
|
||||||
sampling_params = getattr(self.requests[req_id], "sampling_params", None)
|
decode_req_ids,
|
||||||
extra_args = getattr(sampling_params, "extra_args", None) if sampling_params is not None else None
|
req_input_ids.device,
|
||||||
seed = None
|
)
|
||||||
if isinstance(extra_args, dict):
|
generator = None
|
||||||
seed = extra_args.get("tts_local_seed")
|
generators = None
|
||||||
return int(seed) if seed is not None else None
|
if row_generators is not None:
|
||||||
|
if decode_batch_size == 1:
|
||||||
def _row_generator(req_id: str) -> torch.Generator | None:
|
generator = row_generators[0]
|
||||||
seed = _explicit_talker_seed(req_id)
|
elif getattr(self.model, "talker_mtp_accepts_generators", False):
|
||||||
if seed is None:
|
# Unseeded rows intentionally keep the default global RNG semantics,
|
||||||
return None
|
# represented by None, even when batched with explicitly seeded rows.
|
||||||
cache = getattr(self, "_talker_mtp_generators", None)
|
generators = row_generators
|
||||||
if cache is None:
|
else:
|
||||||
cache = {}
|
self._talker_mtp_forward_row_by_row(decode_req_ids, inputs_embeds, start_offsets)
|
||||||
self._talker_mtp_generators = cache
|
return
|
||||||
generator = cache.get(req_id)
|
|
||||||
if generator is None or generator.device != req_input_ids.device:
|
|
||||||
generator = torch.Generator(device=req_input_ids.device)
|
|
||||||
generator.manual_seed(seed)
|
|
||||||
cache[req_id] = generator
|
|
||||||
return generator
|
|
||||||
|
|
||||||
row_generators = [_row_generator(req_id) for req_id in decode_req_ids]
|
|
||||||
cache = getattr(self, "_talker_mtp_generators", None)
|
|
||||||
if cache:
|
|
||||||
# Generators live as long as their request; drop finished ones.
|
|
||||||
for stale_id in [rid for rid in cache if rid not in self.requests]:
|
|
||||||
del cache[stale_id]
|
|
||||||
|
|
||||||
if (
|
|
||||||
decode_batch_size > 1
|
|
||||||
and any(generator is not None for generator in row_generators)
|
|
||||||
and not getattr(self.model, "talker_mtp_accepts_per_row_generators", False)
|
|
||||||
):
|
|
||||||
# A torch.Generator is a single stream. Using one generator for a
|
|
||||||
# multi-row batch would make explicitly-seeded requests depend on
|
|
||||||
# other rows in the same scheduler step, so keep that path scalar.
|
|
||||||
saved_input_ids = self.talker_mtp_input_ids.gpu[:decode_batch_size].clone()
|
|
||||||
saved_embeds = self.talker_mtp_inputs_embeds.gpu[:decode_batch_size].clone()
|
|
||||||
saved_hidden = self.last_talker_hidden.gpu[:decode_batch_size].clone()
|
|
||||||
saved_text = self.text_step.gpu[:decode_batch_size].clone()
|
|
||||||
try:
|
|
||||||
for row, req_id in enumerate(decode_req_ids):
|
|
||||||
self.talker_mtp_input_ids.gpu[:1].copy_(saved_input_ids[row : row + 1])
|
|
||||||
self.talker_mtp_inputs_embeds.gpu[:1].copy_(saved_embeds[row : row + 1])
|
|
||||||
self.last_talker_hidden.gpu[:1].copy_(saved_hidden[row : row + 1])
|
|
||||||
self.text_step.gpu[:1].copy_(saved_text[row : row + 1])
|
|
||||||
row_offsets = None if start_offsets is None else [start_offsets[row]]
|
|
||||||
self._talker_mtp_forward([req_id], inputs_embeds, row_offsets)
|
|
||||||
finally:
|
|
||||||
self.talker_mtp_input_ids.gpu[:decode_batch_size].copy_(saved_input_ids)
|
|
||||||
self.talker_mtp_inputs_embeds.gpu[:decode_batch_size].copy_(saved_embeds)
|
|
||||||
self.last_talker_hidden.gpu[:decode_batch_size].copy_(saved_hidden)
|
|
||||||
self.text_step.gpu[:decode_batch_size].copy_(saved_text)
|
|
||||||
return
|
|
||||||
|
|
||||||
talker_kwargs = {
|
talker_kwargs = {
|
||||||
"do_sample": subtalker_params.get("do_sample"),
|
"do_sample": subtalker_params.get("do_sample"),
|
||||||
@@ -1881,11 +1920,10 @@ class OmniGPUModelRunner(GPUModelRunner):
|
|||||||
"top_k": subtalker_params.get("top_k"),
|
"top_k": subtalker_params.get("top_k"),
|
||||||
"top_p": subtalker_params.get("top_p"),
|
"top_p": subtalker_params.get("top_p"),
|
||||||
}
|
}
|
||||||
if decode_batch_size == 1:
|
if generator is not None:
|
||||||
if row_generators[0] is not None:
|
talker_kwargs["generator"] = generator
|
||||||
talker_kwargs["generator"] = row_generators[0]
|
if generators is not None:
|
||||||
elif any(generator is not None for generator in row_generators):
|
talker_kwargs["generators"] = generators
|
||||||
talker_kwargs["generators"] = row_generators
|
|
||||||
if getattr(self.model, "talker_mtp_accepts_req_infos", False):
|
if getattr(self.model, "talker_mtp_accepts_req_infos", False):
|
||||||
talker_kwargs["req_ids"] = decode_req_ids
|
talker_kwargs["req_ids"] = decode_req_ids
|
||||||
talker_kwargs["req_infos"] = [
|
talker_kwargs["req_infos"] = [
|
||||||
|
|||||||
Reference in new issue
Block a user