mstar.model.omnivoice.components.backbone#
The OmniVoice backbone, run as one packed bidirectional forward per step.
A request in a step becomes two documents — the conditional canvas and its CFG counterpart — packed end to end into a single row and separated by flashinfer’s ragged attention rather than by a mask, or one document when it turned CFG off. Nothing is padded, so a batch mixing a 2-second and a 25-second utterance wastes nothing, and the head GEMM runs only at the positions whose logits are read.
The per-step kernel path is the reference’s own fastest mode, reused rather than
re-derived: apply_flashinfer fuses QKV, swaps in flashinfer RoPE, RMSNorm
and silu_and_mul, and keeps the whole layer in (S, H, D) so no transpose
copies happen. Re-implementing that here would mean a second copy of tuned
kernels whose only job is to end up numerically identical.
What M* adds on top is what the reference cannot do from inside one
generate() call: the documents in a step come from different concurrent
requests, at different diffusion steps, with different per-request knobs. Its
own server has no batching at all (k2-fsa/OmniVoice#251).
The coupling to omnivoice.models.omnivoice_flashinfer is deliberate but
narrow — four module-private names, checked at load by assert_flashinfer_api
so an upstream rename fails at boot rather than at the first request.
Functions
Fail at boot if the reference's private surface moved. |
|
|
Pack a step's requests into one ragged row. |
Classes
|
One request's contribution to a step's packed batch. |
|
The patched reference model, driven one packed step at a time. |
|
One step's packed inputs, plus the index that gathers its logits. |
- class mstar.model.omnivoice.components.backbone.CanvasItem(request_id, prefix_ids, prefix_audio_mask, tokens, guidance_scale, flat_start=-1, flat_u_start=-1)[source]#
Bases:
objectOne request’s contribution to a step’s packed batch.
prefix_idsis[C, N]— style tokens, then text tokens, then the reference audio tokens when cloning.tokensis[1, C, T], the live target canvas: all MASK at step 0, fully revealed when the loop ends.An item at
guidance_scale == 0contributes one document instead of two. Scoring throws the unconditional logits away in that case, and the unconditional document is the whole target region plus its share of the head GEMM, so building it would be close to twice the work for nothing.- Parameters:
- class mstar.model.omnivoice.components.backbone.OmniVoiceBackbone(model, plan_dtype)[source]#
Bases:
ModuleThe patched reference model, driven one packed step at a time.
Holding the reference instance rather than borrowing its submodules is what keeps the embedding merge, the audio head reshape and the fused attention path byte-for-byte the upstream ones; every line of per-step math that could drift is theirs.
- forward(canvas)[source]#
One packed forward; returns
[1, C, 2 * flat_target_total, V].Only the logits-consuming positions go through the 1024 -> 8200 head GEMM and the float32 upcast. Running them over the full packed length would be several times the work, most of it on prefix positions whose logits are never read.
- Parameters:
canvas (PackedCanvas)
- Return type:
- class mstar.model.omnivoice.components.backbone.PackedCanvas(packed_ids, audio_mask, position_ids, doc_lens, tgt_index, flat_target_total, flat_uncond_total, items)[source]#
Bases:
objectOne step’s packed inputs, plus the index that gathers its logits.
- Parameters:
- items: list[CanvasItem]#
- slice_logits(logits, item)[source]#
Conditional and unconditional target logits for one item.
Laid out as every item’s conditional target block followed by the unconditional blocks of the items that asked for CFG, which is the gather order
tgt_indexwas built in.The unconditional half is
Nonefor an item atguidance_scale == 0: it has no unconditional document, because scoring would discard those logits anyway.- Parameters:
logits (Tensor)
item (CanvasItem)
- Return type:
- mstar.model.omnivoice.components.backbone.assert_flashinfer_api()[source]#
Fail at boot if the reference’s private surface moved.
These names are private to
omnivoice. Pinning them here means an upgrade that renames one produces a clear error on startup instead of a silent fallback or a first-request crash.
- mstar.model.omnivoice.components.backbone.build_packed_canvas(items, audio_mask_id, device)[source]#
Pack a step’s requests into one ragged row.
Documents are laid out
[cond_0, uncond_0, cond_1, uncond_1, ...]and kept apart by the attention plan’sdoc_lens, not by a mask — so there are no pad positions at all, and therefore none of the fully-masked-row hazard a dense padded batch has to guard against.An item at
guidance_scale == 0contributes only its conditional document, so a batch of those is close to half the packed length and half the head GEMM. Mixing the two kinds in one step is fine: the layout is driven per item.position_idsrestart at 0 in every document. Without that, RoPE would read a later document’s canvas as a continuation of the previous request’s.- Parameters:
items (list[CanvasItem])
audio_mask_id (int)
device (device)
- Return type: